Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DateTime, the Epoch and DocumentDb

So I read this very interesting blog on working with datetime in Azure DocumentDb. The problem being that, right now, Azure DocumentDb does not support range search on datetime fields. The reason for that is that DocumentDb is based on json and that has no datetime type, therefore one usually puts it in a string of xml datetime format.

(obviously Mongo does not have that issue, it's bson format adds the datetime type (among others))

Anyway, the article describes storing the datetime in json in an epoch (unix) time, essentially storing the datetime as an amount of seconds since 01-01-1970. One problem of epoch is that it does not take leap seconds into account, but I can live with that for now.

My question is that I would also like to store birth dates in such a format. Now I could just take 01-01-1900 as a start date and store the amount of days since that date in an int. While I am pretty sure this would work well, it feels like epoch is a well established concept, but the one for birthdays feels like I am building my own conventions, which is something I generally like to avoid.

Is there any established standard for standardizing date storage as a number? Which date should be the baseline date?

like image 813
Gerben Rampaart Avatar asked Aug 12 '15 19:08

Gerben Rampaart


People also ask

What is epoch date in Unix?

Literally speaking the epoch is Unix time 0 (midnight 1/1/1970), but 'epoch' is often used as a synonym for Unix time. Some systems store epoch dates as a signed 32-bit integer, which might cause problems on January 19, 2038 (known as the Year 2038 problem or Y2038).

How to convert Python Epoch time to datetime?

Let us see with the below example on Python epoch to DateTime. In this example I have imported the datetime package and taken the variable as epoch time and value to the variable like the number of seconds and used datetime.datetime.fromtimestamp (epochtime) method to convert the epoch time to DateTime. Below image shows the output:

How do you convert epoch to human readable date in Excel?

Convert from epoch to human-readable date. =(A1 / 86400) + 25569 Format the result cell for date/time, the result will be in GMT time (A1 is the cell with the epoch number). For other time zones: =((A1 +/- time zone adjustment) / 86400) + 25569.

How to get epoch from datetime from strftime?

strftime () is used to convert string DateTime to DateTime. It is also used to convert DateTime to epoch. We can get epoch from DateTime from strftime (). The parameter %s is a platform dependent format code, it works on Linux. In windows, the same code can be modified to run by %S in place of %s. we can get epoch from DateTime using timestamp ().


3 Answers

First of all, an update: DocumentDB now supports range indexes on both strings and numbers. You have to set up the indexes correctly for it to work.

Now, to give you a recommendation. I've been successful storing ISO-8601 timestamps as strings. This is the default format used by the DocumentDB SDK for handling DateTime so it's less work than converting to an integer.

ISO-8601 date/time strings have several properties that match your needs.

  1. The alpha-numeric sort order is chronological so it works perfectly as expected with query clauses using >, <, >=, <=, and BETWEEN assuming you have a range index of appropriate precision (-1 for full precision);
  2. They are human readable so if you are browsing a table, the data makes sense;
  3. This format allows for the specification of lower granularity date/time. For instance, you should say "2015-03" to mean the month of march, or "2015-03-24" to mean March 24, 2015. You can then issue a query with this filter "startedOn >= 2015-03-24 AND startedOn < 2015-03-25" to find everything that started on March 24, 2015. This works even when startedOn is stored as a full ISO-8601 string like "2015-03-24T12:34:56.789Z" due to the nature of string comparison.

I've written about this approach here.

like image 192
Larry Maccherone Avatar answered Sep 27 '22 18:09

Larry Maccherone


The answer by Teo is correct, except that I suspect in terms of being "well established", the billions of Microsoft Excel, LibreOffice, and Lotus 1-2-3 spreadsheets with their own epoch may far outnumber Unix Time usage. Or the billion of Apple Cocoa devices and computers with their own epoch.

Be aware that a couple dozen different epochs have been used by various computer environments. Unix time is far from being alone or even dominant.

Also be aware that there is no such thing as Unix time exactly. Variations include using whole seconds, milliseconds, microseconds, or nanoseconds.

When possible, use a date-time savvy data type. Be sure to study the doc and experiment to understand clearly it's behavior.

Where not possible to use a data type, fallback to using a string in the various ISO 8601 formats. Some of those standard formats are alphabetically chronological in sorting, especially for date-only values: YYYY-MM-DD.

Leap seconds are ignored in every date-time tracking system I know of. Their purpose is to make our hourly clock jive with calendar, so for business purposes the Leap Second is in a sense meant to be ignored.

Date-time work is surprisingly tricky and slippery business. Search StackOverflow to discover the many issues. Try to avoid rolling your own solutions. For C# in particular, look at the Noda Time library.

like image 45
Basil Bourque Avatar answered Sep 27 '22 18:09

Basil Bourque


In my experience i haven't encountered a more 'established' standard than the UNIX epoch. This being said, some architectural/technological aspects of time storage have been discussed before: Timestamps and time zone conversions in Java and MySQL

I would ask why risk using your own convention? It's a risk because: what if some time you will want to add hours to your day count, maybe to be able to order people based on when exactly during the day they were born. The question can be extended to: what if at some point you want to measure more generic or more fine-grained moments; you would have to translate your entire feature, possibly throughout many layers of your application, to a more generic mechanism/convention. Another (similar) question would be: will you always measure once-in-a-lifetime events for the people in your database or will they be able to create new, unlimited events? As the number of events increases the risk of collision increases too and a day count would not be as suitable as a timestamp measured in seconds or milliseconds.

UNIX time is basically ubiquitous, you have special methods for getting it in most programming languages. The time-keeping architecture i will always support & implement in my projects is this: http://www.currentmillis.com/tutorials/system-currentTimeMillis.html

Architecture that stores time as a number

As also stated in my answer to the question linked above, the advantages of storing time as milliseconds since the UNIX epoch are:

  • architecture clarity: server side works with UTC, client side shows the time through its local timezone
  • database simplicity: you store a number (milliseconds) rather than complex data structures like DateTimes
  • programming efficiency: in most programming languages you have date/time objects capable of taking milliseconds since Epoch when constructed (which allows for automatic conversion to client-side timezone)

Because you mentioned C#, DateTime.MinValue comes to mind. This would basically be the year 0 (midnight, 1st of January).

Also, this would be some code which would allow you to get the millis since your chosen reference date (whatever it is) but note that 1900 is still different than .NET's 'epoch' (DateTime.MinValue)

// Unix Epoch
(DateTime.UtcNow - new DateTime (1970, 1, 1)).TotalMilliseconds
// NTP Epoch
(DateTime.UtcNow - new DateTime (1900, 1, 1)).TotalMilliseconds
like image 28
Sandman Avatar answered Sep 27 '22 18:09

Sandman