2

A tricky situation here. Our application runs in a system that is set with a particular TimeZone (let's say Asia time). However a client request that his application to be run using Europe timezone.

Since our data are not stored in UTC, is there anyway we can set the locale in the application so that all dates displayed will be using Europe TimeZone? I understand that we can set the Culture info at the Web.Config but i'm not sure whether that can help set the TimeZone as well.

BTW our application is running using C# WebForm and MSSQL 2008 R2.

ipohfly
  • 1,959
  • 6
  • 30
  • 57
  • Refer. Link... It will help to u... http://msdn.microsoft.com/en-us/library/bb382770.aspx – Niks Mar 15 '13 at 07:02

3 Answers3

2

How your data is stored is entirely separate to how you choose to display it. Assuming the dates and times are meant to represent fixed points in time (rather than floating "local" times) I would try to write as much of the application as possible with DateTime values in UTC. When you retrieve data, convert it from your "storage time zone" if you need to (you haven't said which zone your data is stored in) and convert it back when you store it. When you display it, display it in whichever time zone you need to.

You don't need to set this at a global level as far as .NET is concerned - you can have an application-wide configuration setting (if you really want to) and "helper" code to convert it whenever you need to display. I would do so very explicitly though: you really don't want conversions happening implicitly when it comes to time stuff.

(I'd also mention that my Noda Time library may come in useful as a clearer API when it comes to dates and times. I'm biased, of course. I'd also suggest migrating to storing everything in UTC if you can... and only where appropriate, of course.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thanks for the suggestion. However we don't have the option to rewrite the code to put everything into UTC as there is a time constraint with this project. (to be honest i don't even think we have time to write the helper class which is obviously needed but..sigh..) – ipohfly Mar 15 '13 at 07:00
  • @ipohfly: Well, I've said what I think the best course of action is. Without detailed knowledge of your project and the time constraints, it's hard to say just how many hacky shortcuts you should take. I would be very wary of short-term fixes which don't address the underlying problems though. – Jon Skeet Mar 15 '13 at 07:04
  • Thanks. Another question is, even if i were to store all dates in UTC, and format them to local time when display, how about those data that are displayed in RDLC reports? that can be achieved as well? Thanks for your opinion :) – ipohfly Mar 15 '13 at 07:24
  • @ipohfly: I know nothing about RDLC reports, I'm afraid. I'd certainly *hope* they could be tuned, as it must be a pretty common requirement. – Jon Skeet Mar 15 '13 at 09:19
1

You should store your dates with DateTimeOffset:

Represents a point in time, typically expressed as a date and time of day, relative to Coordinated Universal Time (UTC).

Using DateTimeOffset has great advantages, as these dates are easily convertible to any timezone without losing the offset where the event happened (i.e. storing some data in some moment in time).

As Jon Skeet suggested in a comment in my answer, a time zone identifier should be stored along with the DateTimeOffset in order to have the full date+time information and make it fully convertible.

In the other hand, you may not store data in a particular time zone but with a DateTimeOffset as is with the whole time zone identifier, and later you'll convert it to the required time zone depending on user profile's or application-wide time zone and/or culture setting in the application layer.

Finally, you can convert such DateTimeOffset using this TimeZoneInfo.ConvertTime(DateTimeOffset, TimeZoneInfo) overload.

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
  • 2
    `DateTimeOffset` *does* lose the time zone where the event happened. It doesn't lose the local time, but it does lose the time zone. There can be multiple time zones using the same offset at any one point in time. – Jon Skeet Mar 15 '13 at 07:03
  • @JonSkeet In general terms, it doesn't lose it. Time zones are a extremely complex problem, I know (I have read many articles, including some of yours! :D). Depending on the demography entering to your site, `DateTimeOffset` can be enough, what do you think? – Matías Fidemraizer Mar 15 '13 at 07:05
  • 1
    In *general* terms it certainly does lose it. In some *specific* cases, it may not. But if you actually care about the time zone, you should know it and store it. If you only care about the local time at that instant, then `DateTimeOffset` is fine. I'm not saying that `DateTimeOffset` is always inappropriate - although in many cases you really *don't* need to know the original local time, and a UTC `DateTime` is fine - I'm mostly arguing against your claim that it doesn't lose the time zone. – Jon Skeet Mar 15 '13 at 07:08
  • See http://pastebin.com/gqLuczai for some code to show the number of time zones (even in the fairly small Windows DB) observing any particular offset at the moment. – Jon Skeet Mar 15 '13 at 07:16
  • @JonSkeet Thanks for the effort, I'll check your comment and sample code in less than an hour (I'm having breakfast!!). Thanks!! – Matías Fidemraizer Mar 15 '13 at 07:24
  • @JonSkeet, Sorry for the delay. In summary, how would you store a full DateTimeOffset with TimeZone info in a data store like a DB? – Matías Fidemraizer Mar 15 '13 at 08:26
  • You'd store the time zone ID. You don't even need the full DateTimeOffset - just the UTC DateTime and the TimeZoneInfo ID is enough. – Jon Skeet Mar 15 '13 at 08:35
  • @JonSkeet As far as I know (if I'm not wrong), Windows assigned time zone identifiers aren't an actual standard, but a _de facto_ standard. This is a problem in terms of data neutrality. I believe there's an actual standard for this aside of the Windows one. – Matías Fidemraizer Mar 15 '13 at 08:42
  • Well, using the TZDB IDs is probably the best bet for portability - but that means going away from `TimeZoneInfo` and using something like my Noda Time project. – Jon Skeet Mar 15 '13 at 08:43
  • @JonSkeet Is your project, Noda Time, still under development, or are you still maintaining it? – Matías Fidemraizer Mar 15 '13 at 08:55
  • @JonSkeet In instance, check my updated text in my answer. I believe it's more accurate thanks to your points. – Matías Fidemraizer Mar 15 '13 at 08:56
  • Noda Time 1.0 is out and stable; I'm hoping to get 1.1 (primarily PCL support) released in the next couple of weeks. – Jon Skeet Mar 15 '13 at 09:19
  • @JonSkeet I'll look forward for using it, at least in some personal projects. Based on a lot of articles I've reading these years, I'm agree about .NET has a poor built-in support for globalized date and times. – Matías Fidemraizer Mar 15 '13 at 09:27
  • @MatíasFidemraizer If you haven't already, you should also [read this](http://stackoverflow.com/a/14268167/634824) - then check out nodatime. :) – Matt Johnson-Pint Mar 16 '13 at 16:12
  • This doesn't answer the question. – BartoszKP Oct 05 '16 at 13:36
  • @MatíasFidemraizer What I mean is that the question asks "How to do X" and the answer is "Do Y instead", not explaining how to do X, nor stating that X is impossible. – BartoszKP Oct 06 '16 at 11:55
  • @BartoszKP BTW I remember that I added this answer because I thought that OP should know that mostly `DateTime` should be avoided – Matías Fidemraizer Oct 06 '16 at 13:07
  • @BartoszKP I mean... this answer isn't 100% an answer for this Q&A, but it's a good advise, isn't it? – Matías Fidemraizer Oct 06 '16 at 13:10
  • @MatíasFidemraizer It may be a good advise :) For me it isn't - I know it already and in the code-base I've got it's impossible to implement. So I was interested in exactly what the question asks, even if just out of curiosity. So, for me, this is misleading :) From what I've manage to learn by now, the answer to the question seems to be "it's impossible" (however, I didn't find any credible source for this information) - so perhaps that would be a valuable addition to your answer ;) – BartoszKP Oct 07 '16 at 09:02
  • @BartoszKP If I understood you well, you got into the case that you've a system which has been already implemented without using `DateTimeOffset`? – Matías Fidemraizer Oct 07 '16 at 10:48
  • @MatíasFidemraizer Yes, and it's a large code base (hundreds thousands of LOC). I needed to write some units tests to document an existing behaviour of a class before refactoring - and this class uses `.ToLocal()`. – BartoszKP Oct 07 '16 at 20:39
1

How about changing locale?

CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
if (currentCulture.Name != "sv-SE")
{
    // Change the current culture to sv-SE and serialize the date.
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("sv-SE");
}

// Do something with a date in swedish timeZone
var swedishNow = DateTime.Now;

// Restore back to the original culture, when finished
Thread.CurrentThread.CurrentCulture = currentCulture;
RaSor
  • 869
  • 10
  • 11