tags:

views:

8715

answers:

3

I'm trying to create a unit test to test the case for when the timezone changes on a machine because it has been incorrectly set and then corrected.

In the test I need to be able to create DateTime objects in a none local time zone to ensure that people running the test can do so successfully irrespective of where they are located.

From what I can see from the DateTime constructor I can set the TimeZone to be either the local timezone, the UTC timezone or not specified.

How do I create a DateTime with a specific timezone like PST?

+1  A: 

You'll have to create a custom object for that. Your custom object will contain two values:

Not sure if there already is a CLR-provided data type that has that, but at least the TimeZone component is already available.

Jon Limjap
+11  A: 

Jon's answer talks about TimeZone, but I'd suggest using TimeZoneInfo instead.

Personally I like keeping things in UTC where possible, so I'd suggest a structure like this:

public struct DateTimeWithZone
{
    private readonly DateTime utcDateTime;
    private readonly TimeZoneInfo timeZone;

    public DateTimeWithZone(DateTime dateTime, TimeZoneInfo timeZone)
    {
        utcDateTime = TimeZoneInfo.ConvertTimeToUtc(dateTime, timeZone); 
        this.timeZone = timeZone;
    }

    public DateTime UniversalTime { get { return utcDateTime; } }

    public TimeZoneInfo TimeZone { get { return timeZone; } }

    public DateTime LocalTime
    { 
        get 
        { 
            return TimeZoneInfo.ConvertTime(utcTime, timeZone); 
        }
    }        
}

You may wish to change the "TimeZone" names to "TimeZoneInfo" to make things clearer - I prefer the briefer names myself.

Jon Skeet
will this kind of struct map to a IQueryable interface on LinqToSql? coz any time i've tried to use another object instead of DateTime or DateTime? on my LinqToSql mapping, it fails when i query it.. u prob know the exception: "..can not convert to SQL.."
cottsak
I don't know of any equivalent SQL Server construct, I'm afraid. I would suggest having the time zone name as one column, and the UTC value in another column. Fetch them separately and then you can create instances fairly easily.
Jon Skeet
Not sure about the expected use of the constructor that takes a DateTime and TimeZoneInfo, but given that you're calling the dateTime.ToUniversalTime() method, I suspect you are guessing it to "maybe" be in local time. In that case, I think you should really be using the passed-in TimeZoneInfo to convert it to UTC since they're telling you it is supposed to be in that timezone.
IDisposable
Yup, I think you're right. Fixing...
Jon Skeet
+4  A: 

The DateTimeOffset structure was created for exactly this type of use.

See: http://msdn.microsoft.com/en-us/library/system.datetimeoffset.aspx

Here's an example of creating a DateTimeOffset object with a specific time zone:

DateTimeOffset do1 = new DateTimeOffset(2008, 8, 22, 1, 0, 0, new TimeSpan(-5, 0, 0));

Clever Human
Thanks, this is a good way to accomplish it. After you get your DateTimeOffset object within the right timezone, you can use the .UtcDateTime property to get a UTC time for the one you created. If you store your dates in UTC, then converting them to local time for each user is no big deal :)
Redth