how many time zones are there? - c#

I'm not sure whether this is an SO question but still would like to know the answer.
Wikipedia says there are about 40 time zones, but when I invoke the TimeZoneInfo.GetSystemTimeZones() method in c# it returns a list of 101 elements.
Is the wiki article outdated (though it "was last modified on 26 April 2012 at 05:11") or are there any additional time zones?

There's no one answer - it depends on what time zone database you're interested in. Using TimeZoneInfo.GetSystemTimeZones will use the Windows time zones... if you use tzdb you're likely to see a lot more.
(The current Noda Time version returns 575 time zone IDs, for example, although that includes Etc/GMT+9, Etc/GMT+10 etc.)

Related

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?
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.
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);
They are human readable so if you are browsing a table, the data makes sense;
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.
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.
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
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

TimeZoneInfo.ConvertTimeToUtc vs TimeZone.ToUniversalTime vs DateTime.ToUniversalTime [duplicate]

This question already has an answer here:
What is this about adjustment rules when converting DateTime to UTC?
(1 answer)
Closed 7 years ago.
From https://msdn.microsoft.com/en-us/library/bb397769(v=vs.110).aspx
The TimeZoneInfo.ConvertTimeToUtc(DateTime) method does not necessarily produce results that are identical to the TimeZone.ToUniversalTime and DateTime.ToUniversalTime methods. If the host system's local time zone includes multiple adjustment rules, TimeZoneInfo.ConvertTimeToUtc(DateTime) applies the appropriate rule to a particular date and time. The other two methods always apply the latest adjustment rule.
Please can someone explain this more clearly, preferably with examples?
"Multiple adjustment rules" applies to having different rules for different years. Pretty common, daylight savings time rules are political decisions that often change. The TimeZone class only applies the current rule, even to historical dates. TimeZoneInfo can know about rules that were in effect in the past.
This ultimately depends on a database that keeps track of those rules. You can have a look-see at it, fire up Regedit.exe on Windows and navigate to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones. The "Israel Standard Time" key is an interesting one to peek at, their rules constantly change. Note the listed years in the Dynamic DST key. Compare to the Wikipedia article about it and note that it isn't complete, you'll see the mayhem before 2004 missing. As noted in the article, Microsoft gave up on trying to keep it accurate for a while.
In general, a machine needs to have Windows Update enabled to reliably keep track of rule changes.

Is there anything that reduces the Olson time zone list into a readable format for the UI (like Google Calendar does)?

I am writing an app that asks the user to choose a time zone. I am getting my list of time zones from the Olson database (via NodaTime) but that is a massive list with many redundant entries, for my purposes at least.
When you create an event on Google Calendar it lets you choose the time zone from a relatively small list with ordering by country where necessary. I would like to be able to achieve something as simple as that without creating a separate database, which is what
this person does.
Because I am writing this in C# MVC plus JavaScript on the front end, I am looking for a library in either of those languages that gives me a reduced list in a user-friendly format that I could display in a dropdown. Is there such a thing or do I have to create my own and regularly keep it up to date, like the example shown in the hyperlink?
Two possible answers here:
Information from the zone.tab file. As it happens, just today another contributor mailed the list with an hg clone which uses this data. I haven't looked at it yet, but hope to do so over the weekend - and after a bit of massaging, we'll hopefully get it into the 1.1 branch.
Information from CLDR. This provides suggested example cities to present to a user - it's designed for exactly this purpose (even localized, I believe). However, you'd need to integrate this with Noda Time yourself; we don't currently have any code for this, and just getting to grips with CLDR will take some time.
Apologies for this not being solved out of the box - but we're aware of it and hope to provide an answer over time.

Local to GMT DateTime Conversion

I'm working with the Amazon API. I need to convert local time (EDT) to a DateTime that complies with the following documentation from Amazon:
You can specify the FulfillmentDate with or without time zone information:
2006-12-11T09:50:00 - local time zome applies
2006-12-11T09:50:00+02:00 - GMT time zone applies
For locales affected by Daylight Saving Time, adjust the information, if necessary.
Daylight Saving Time is not automatically taken into consideration.
I thought I needed to do something like shown in this SO thread, but apparently wrong, because when I upload the date using that method, Amazon shows it as a day before. I can confirm this by using this online converter tool.
For example:
My local time is "7/25/2012 00:00:00" (EDT).
Using above SO method, and formatted, it's now
"2012-07-25T01:00:00-04:00".
But it converts to the 24th, specifically "Tuesday, July 24, 2012 at
21:00:00".
Obviously I'm doing something wrong here - I'd appreciate if someone can enlighten me.
Thank you!
I would recommend using:
String xmlDateString = XmlConvert.ToString(DateTime.UtcNow,XmlDateTimeSerializationMode.Local);
Obviously Amazon converts your local time information back to UTC time (which is based on your input 4 hours back in time: Tuesday, July 24, 2012 at 21:00:00 and therefore correct).
Which result have you been expected?
I think I can introduce a "joda time" project written by Jon Skeet. You can refer to link pros and cons of joda time

How to convert UTC time to Time in any other time zone in C#

I am working in C#.net - .Net fx is 2.0 which doesnot support converting between different time zones. I have wrote a scheduler based on UTC but it is giving errors of 1 hour in the DTS periods for London. I need some solution so that I can gat the correct time in any timezone relative to UTC with correct DST adjustments.
Is changing to .NET 3.5 absolutely out of the question? It would make your life much, much easier. Otherwise, you're stuck with the plain TimeZone and DaylightSavings classes, as well as having to fetch the known timezones using P/Invoke.
William Stacey has a blog post with some code to do this - but I haven't tried it, so can't vouch for its accuracy. (In my experience he's usually pretty good though :) There are no doubt similar bits of code around if that one doesn't help you.
I believe that the API he's using doesn't have access to historical data, btw. In other words, it will assume that DST always kicks in on the first Sunday of October (or whatever the rule is) rather than knowing that the rule has changed over time. TimeZoneInfo in .NET 3.5 supports historical data where the OS does.

Categories

Resources