RealSteel
RealSteel

Reputation: 1941

NodaTime get Country Time based on CountryCode

I've a requirement where Admin will select some countries List and Time for Alert for users for that Countries List.

Lets Say the Admin selects 24/07/2014 09:00 AM in the Countries India,Malaysia and Canada, They need to get the Alerts based on their TimeZone and every country user need to get the Alert at the User's Local 9 AM Time.

So,I only have their country Codes like IN,MY,CA

So,I thought of getting their TimeZones and calculating based on the Server Time.

For Example : My Server is Located in Canada.So,I thought of calculating the Time to Alert in India based on the India TimeZone and save the Time in Db.So my windows service will run at that India Time and push the Alert.

But for this,I need to save multiple records with different times in Db.

So,For getting the TimeZone based on the CountryCode, I've used NodaTime

var CountryInfo = (from location in TzdbDateTimeZoneSource.Default.ZoneLocations
                     where location.CountryCode.Equals(CountryCode,
                           StringComparison.OrdinalIgnoreCase)
                     select new { location.ZoneId, location.CountryName })
                 .FirstOrDefault();

I'm getting the TimeZoneID from this Query.
Can we get the CurrentDate and Time of the CountryCode based on the Admin's Selected DateTime?

Upvotes: 1

Views: 2975

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1503140

Your code is nearly correct - although it can be simplified somewhat, and made more testable, and it should handle the case where there's no such zone...

// You should use dependency injection really - that makes the code much more
// testable. Basically, you want an IClock...
IClock clock = SystemClock.Instance;

var countryCode = "IN";
var location = TzdbDateTimeZoneSource.Default.ZoneLocations
                 .FirstOrDefault(l => l.CountryCode == countryCode);
if (location == null)
{
    // This is up to you - there's no location with your desired country code.
}
else
{
    var zone = DateTimeZoneProviders.Tzdb[location.ZoneId];
    var zonedNow = clock.Now.InZone(zone);
    // Now do what you want with zonedNow... I'd avoid going back into BCL
    // types, myself.
}

Bear in mind that this assumes there's just one time zone for a country - that's not always the case. Think of the US, where there are lot of time zones...

Upvotes: 7

RealSteel
RealSteel

Reputation: 1941

I got the Date by using this :

string CountryCode = "IN";

                var CountryInfo = (from location in TzdbDateTimeZoneSource.Default.ZoneLocations
                                   where location.CountryCode.Equals(CountryCode,
                                              StringComparison.OrdinalIgnoreCase)
                                   select new { location.ZoneId, location.CountryName })
                 .FirstOrDefault();

                var TimeZone = DateTimeZoneProviders.Tzdb[CountryInfo.ZoneId];
                DateTime objdate = Instant.FromDateTimeUtc(DateTime.UtcNow)
                          .InZone(TimeZone)
                          .ToDateTimeUnspecified();

Upvotes: 2

Related Questions