I have local time in string format: "yyyy-MM-dd HH:mm:ss" and an IANA Time Zone for that time (e.g. "Europe/London").
How do I convert that in C#, maybe using NodaTime, to a UTC+TimeZone Offset string
e.g. "yyyy-MM-dd HH:mm:ss+01:00" ?
I don't even know where to start!
This is as far as I get (I am afraid I'm new to C sharp): I understand I need to convert it to an instant, but just can't get to grips with the library.
string dateTime = "2014-12-31 12:30:00";
string IANA = "Europe/London";
Instant instDateTime = NodaTime.Instant.FromDateTimeUtc(Convert.ToDateTime(dateTime));
string outputUTC = string.Format("yyyy-MM-dd HH:mm:ssZ", instDateTime);
Thanks to Matt (see answer below), I now have the functions I needed (Note that in the end what I needed was UTC and not date time + offset):
What is a little worrying is that is says that Europe/Moscow is UTC+04:00, whereas it is actually UTC+03:00 since 26 October 2014.
static void Main(string[] args)
{
string dateTime = "2014-12-31T12:30:00";
string timeZone = "Europe/Moscow";
Console.WriteLine(timeZone + " Local time '" + dateTime + "' to Zulu time");
Console.WriteLine(ConvertIANALocalTimeToZulu(timeZone, dateTime));
Console.WriteLine();
Console.WriteLine("Zulu time '" + dateTime + "' to " + timeZone + " local time");
Console.WriteLine(ConvertZuluTimeToIANALocalTime(timeZone, dateTime));
Console.ReadLine();
}
static string ConvertIANALocalTimeToZulu(string timeZoneIANA, string localDateTime)
{
var pattern = LocalDateTimePattern.CreateWithInvariantCulture("yyyy-MM-ddTHH:mm:ss");
LocalDateTime ldt = pattern.Parse(localDateTime).Value;
ZonedDateTime zdt = ldt.InZoneLeniently(DateTimeZoneProviders.Tzdb[timeZoneIANA]);
Instant instant = zdt.ToInstant();
ZonedDateTime zulu = instant.InUtc();
////string output = zulu.ToString("yyyy-MM-dd HH:mm:sso<m>", CultureInfo.InvariantCulture);
string output = zulu.ToString("yyyy-MM-ddTHH:mm:ss", CultureInfo.InvariantCulture);
return output;
}
static string ConvertZuluTimeToIANALocalTime(string timeZoneIANA, string zuluDateTime)
{
var pattern = InstantPattern.CreateWithInvariantCulture("yyyy-MM-ddTHH:mm:ss");
Instant instant = pattern.Parse(zuluDateTime).Value;
ZonedDateTime zdt = instant.InZone(DateTimeZoneProviders.Tzdb[timeZoneIANA]);
////string output = zdt.ToString("yyyy-MM-dd HH:mm:sso<m>", CultureInfo.InvariantCulture);
string output = zdt.ToString("yyyy-MM-ddTHH:mm:ss", CultureInfo.InvariantCulture);
return output;
}
It's unclear from your question if you meant that the original value was in UTC or in local time.
If it's in UTC, then do the following:
string dateTime = "2014-12-31 12:30:00";
string timeZone = "Europe/London";
var pattern = InstantPattern.CreateWithInvariantCulture("yyyy-MM-dd HH:mm:ss");
Instant instant = pattern.Parse(dateTime).Value;
ZonedDateTime zdt = instant.InZone(DateTimeZoneProviders.Tzdb[timeZone]);
string output = zdt.ToString("yyyy-MM-dd HH:mm:sso<m>", CultureInfo.InvariantCulture);
If it's in local time, then do this instead:
string dateTime = "2014-12-31 12:30:00";
string timeZone = "Europe/London";
var pattern = LocalDateTimePattern.CreateWithInvariantCulture("yyyy-MM-dd HH:mm:ss");
LocalDateTime ldt = pattern.Parse(dateTime).Value;
ZonedDateTime zdt = ldt.InZoneLeniently(DateTimeZoneProviders.Tzdb[timeZone]);
string output = zdt.ToString("yyyy-MM-dd HH:mm:sso<m>", CultureInfo.InvariantCulture);
Also - you should note that in December, London is on GMT (UTC+00:00) - so the output of either function will be "2014-12-31 12:30:00+00:00"
for the values you provided.