1

I'm having a problem with Azure SQL server, on my local machine I can save a datetimeoffset into the db and the timezone offset is correctly saved like below

2017-03-31 00:00:00.0000000 -05:00

however on azure is losing the timezone offset, my columns are of datetimeoffset type and I'm getting my datetimeoffset using this DateTimeOffset.UtcNow.UtcDateTime or DateTimeOffset.Now but neither way seems to work, is always being saved like the below

2017-03-31 00:00:00.0000000 +00:00

how can I save the correct DateTimeOffset on Azure SQL server.

Edit: I'm using Entity Framework Code First Migration, I just create the entity and assign the DateTimeOffset using any of the line above and then context.SaveChanges().

var entity = Mapper.Map<CarSearchForm, CarSearches>(model);
 ctx.CarSearches.Add(entity);
 ctx.SaveChanges();

and then automapper profile is like this

CreateMap<CarSearchForm, CarSearches>()
            .ForMember(dest => dest.RequestedDate, opts => opts.MapFrom(src => DateTimeOffset.UtcNow.UtcDateTime))
            .ForMember(dest => dest.PickupTime, opts => opts.MapFrom(src => src.TimePickup))
            .ForMember(dest => dest.DropoffTime, opts => opts.MapFrom(src => src.TimePickup));    

Here is the Model

namespace Data.Entities
{
    public class CarSearches
    {
        public int CarSearchesId { get; set; }
        [Required]
        public string PickupPlace { get; set; }
        [Required]
        public DateTimeOffset PickupDate { get; set; }
        [Required]
        public DateTimeOffset PickupTime { get; set; }
        [Required]
        public DateTimeOffset DropoffDate { get; set; }
        [Required]
        public DateTimeOffset DropoffTime { get; set; }       
        [Required]
        public CarTransmission Transmission { get; set; }
        [Required]
        public DateTimeOffset RequestedDate { get; set; }        
    }

}

enter image description here I'm only interested in the RequestedDate property above, I can't figure it out why is not saving the timezone offset on Azure but works locally.

Thanks

General Electric
  • 1,176
  • 3
  • 21
  • 44

1 Answers1

4

... I'm getting my datetimeoffset using this DateTimeOffset.UtcNow.UtcDateTime or DateTimeOffset.Now

  • The first one is always going to give you a UTC DateTime value (offset +00:00). It is equivalent to DateTime.UtcNow.

  • The second one will give you a DateTimeOffset value, whose local time and offset match the computer where it is running.

    • On your local computer, you see -05:00 because it uses your computer's local time zone setting.

    • On Azure, you see +00:00. This is because most Azure servers and services are set with their time zone to run in UTC.

      In general, this is the best practice for servers, especially those in the cloud. Servers often need to connect with clients all over the world, and interchange data with each other. UTC is the only time zone that is sensible.

Another way to think about it is that if a machine's time zone is set to UTC, DateTime.Now and DateTime.UtcNow will give the same date and time values, but one will have its .Kind property set to DateTimeKind.Local and the other will have it set to DateTimeKind.Utc. Since DateTimeOffset doesn't have a Kind (thankfully), one cannot distinguish between DateTimeOffset.Now and DateTimeOffset.UtcNow on a machine whose time zone is set to UTC.

As far as what to do about it - if you desire some other time zone to be taken into account, you'll first have to know which time zone that is. Then you can use either the TimeZoneInfo class (if you're using Windows time zones), or the Noda Time library (if you're using IANA time zones) to convert the current UTC time to a DateTimeOffset in that particular time zone.

Using TimeZoneInfo:

DateTime utcNow = DateTime.UtcNow;
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTimeOffset easternNow = TimeZoneInfo.ConvertTimeFromUtc(utcNow, tz);

Using Noda Time:

Instant now = SystemClock.Instance.Now;
DateTimeZone tz = DateTimeZoneProviders.Tzdb["America/New_York"];
DateTimeOffset easternNow = now.InZone(tz).ToDateTimeOffset();
Community
  • 1
  • 1
Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • 1
    Very detailed explanation about azure timezone and how it works, based on that I get the following, always store datetime on UTC and convert to local datetime manually specifying the Timezone on my application code. – General Electric Mar 24 '17 at 20:45
  • 1
    Yes, precisely. Consider that your code should exhibit the same behavior and record the same data regardless of where it is hosted or what time zone setting the server happens to be on. – Matt Johnson-Pint Mar 24 '17 at 20:46