I'm trying to convert some dates that I have stored on the server (in UTC). I'd like to convert them to the user's time so it would be pretty for their time zone.
However, I'm not sure about how to go about doing that. What's the best practice to get the user's timezone from the request in the controller?
The timezone is not passed in the request headers. If you had the users time zone stored in a profile setting then you can easily format the date according to this but its not something you can just grab from the request. There are ways to do this in JavaScript.
Related
The user profile page doesn't appear to allow the user to specify their timezone. How should we add this feature so the user can select and save their timezone and then have the web pages display the localised date?
Times are displaying in my browser according to the location of the server, so I edit a record at 7am local time, and it appears as if I edited it 4 hours in the future :)
Best solution for me is to allow the user to specify their timezone on their profile and then have this setting reflected in times displayed in the UI.
I'm set Clock.Provider to the UTC in file Startup.cs of ...Web.Host is OK
// using Abp.Timing;
public Startup(IHostingEnvironment env)
{
// Set Clock.Provider as UTC:
Clock.Provider = ClockProviders.Utc;
//_appConfiguration = env.GetAppConfiguration();
}
If Angular not sent date UTC you can using:
yourDate = abp.timing.convertToUserTimezone(yourDate); // to convert yourDate to date UTC.
You need to set the Clock.Provider to the UTC clock on the server. The documentation tells you that you need to set it but doesn't really tell you where. You just need to set this during the startup process. Here is a link to the docs that touch on it briefly.
Timing Documentation
Hope that helps.
I'm facing one issue in my MVC application. In one module I'm using kendo-ui grid (Ex. #(Html.Kendo().Grid(Model))). Issue is, its change the DateTime object value when it render on the web browser. Ex. If my DateTimeobject value on server side is '2016-09-20 00:00:00' and when it renders on the browser then this value becomes '2016-09-20 05:30:00' (India time zone +5:30), on client side rendering DateTime object value add the time zone value of the user's browser. so my DateTime object value is changed and I do not want to change it. Is there any solution available for this kind of problems?
The date values are changed by the browser, because JavaScript Date objects are represented in the local time zone. The workaround is to use UTC:
http://docs.telerik.com/kendo-ui/aspnet-mvc/helpers/grid/how-to/utc-time-on-both-server-and-client
Quick environment overview:
I have an ASP.NET MVC/AngularJS application that is ultimately being hosted as an Azure Webrole. The data is stored in MongoDB hosted in the same Azure data center (via MongoLab). Development environment and staging environment (Azure) point to same MongoDB database and thus see the exact same data.
Issue:
Individual users of the application are stored with their preferred timezone as a string (TimezoneID). All dates in the app are stored as UTC times. Conversion to and from UTC times to a users specific timezone is done on the server via an extension method which ultimately calls:
return TimeZoneInfo.ConvertTimeFromUtc(UtcDate, _lookup[TimeZoneID]);
Nowhere in the entire app is there a DateTime.Now or any other date conversion I would expect to use the server time settings.
In a particular area of the application a date is being stored in Mongo (UTC). I can confirm that the date is correctly stored as UTC (based on the offset from my local time). When I retrieve that date from the data store and convert it back to my local time (Central Standard Time) I step over the above line of code and the conversion works fine and the local time is set. The result is sent to the client's browser as part of a Json result of an API call and displayed to the user correctly. During transport the MVC Json serializer parses the datetime into a format similar to:
EventDate: "/Date(1399407153971)/"
I parse this in Javascript and display accordingly and all is good.
When I deploy the exact same code to Azure (which points to the exact same data store in Mongo) the result that comes down via the API call appears to have applied the UTC transformation twice (meaning the regular 6 hour UTC offset is applied twice and the displayed date is 12 hours earlier than UTC...6 hours off of what I want).
I've updated the stored time in Mongo by a minute or two to make sure both sides update and they do (verifying the same data). I've modified the date/time settings of my local machine to see if it has any effect on my local results and it does not. I've changed the timezone for the selected user in the app and both my local result AND the Azure returned result adjust by the UTC offset difference between Central Standard Time and the new time zone (meaning if I switch to Mountain Time the result of both the local result and the Azure result adjust by 1 hour...but are still 6 hours off). I've confirmed via Chrome Dev Tools that the date in question that is retrieved at the client (via Json) is different based on whether the site hit was the remove (Azure) environment or local environment (meaning it isn't being modified incorrectly anywhere on the client after-the-fact)
Here is the most telling thing:
If I convert the date to a string prior to returning it to the client the string sent down appears correct in the Json response. If I leave it as a .NET DateTime type (as a property of a complex object) the Json serializer appears to translate it again but ONLY when hosted in Azure. This has pointed me to the issue being somehow related to the DateTimeKind of the date I'm returning. Although, at this point, I'm too lost in the weeks to see why the difference between my local environment and the Azure host environment in serialization and why one things a time is correct and the other converts it twice. If the DateKindTime was wrong wouldn't both environments perform the same conversion?
Thanks for reading through this and I'd appreciate any ideas to address anyone has.
It's difficult to say for sure without seeing more code, but could it be that the problem is with conversion on the way in, rather than on the way out? You said that you're using TimeZoneInfo.ConvertTimeFromUtc for the output. Are you also using TimeZoneInfo.ConvertTimeToUtc on the other side? If so, that's likely the source of picking up your local time zone.
You might also somewhere have a call to DateTime.ToUniversalTime, which again - uses the local time zone.
Another area which might be the culprit - when you retrieve your value from Mongo, check the Kind of the values coming back. If they're Unspecified, then when they are serialized to JSON, they will be treated as if they were Local. basically, there's a ToUniversalTime call going on under the hood. So you may need to explicitly call DateTime.SpecifyKind to set the value to Utc before it goes out the door.
With specific regards to Azure, it follows best practices of setting the server time zone to UTC. You could try that on your own machine and see if you get similar results.
Of course, you really don't want the server's time zone to influence the result at all.
You may want to consider creating a new project with a minimal, complete, and verifiable example. That will help you verify your assumptions, and will likely track down the source of the problem. If it still fails, well then you'll be in much better shape for asking for help.
That was a long post :)
If I were you I would transfer all dateTimes in UTC format. The server basically must work with UTC time as far as I'm concerned. Transformation to client time must be applied at clients side. You can use momentjs library that proved to be very fine library for working with dates and times.
On client side do something like this
var date = {
utc: '/Date(1399407153971)/', //time that you have recieved
offset: 240
}
var localTime = moment.utc(date.utc).zone(date.offset).format('DD/MM/YYYY hh:mm');
I hope this helps
UPD
As Matt Johnson pointed out you can make it even shorter for current time zone.
var localTime = moment('/Date(1399407153971)/').format('DD/MM/YYYY hh:mm');
I am sitting on a really strange issue with grails and the js fullcalendar.
I have users which have their own timezones stored in the database e.g. ECT
When users insert their events all dates are stored in UTC. This is set in the Bootstrap with:
TimeZone.setDefault(TimeZone.getTimeZone("UTC"))
I heard its a good idea to store all dates in UTC. So when a german user is entering 1.12.2012 08:00 its stored with 1.12.2012 07:00. This is fine.
Now when I want to display those values from the db into the calendar the timezone is not considered by fullcalendar(i set ignoreTimezone: false) so the dates are comming over json with 2012-12-01 08:00+01:00 but its display as 08:00 am and not 07:00. What am I doing wrong here? this issue is driving me really crazy.
Can you check in by manually adding the event in javascript?I guess the problem is with the JSON format. The parseISO8601 function inside fullcalendar.js expects your object to be in some format and so if your format is not correct,then you have to experiment and see what works.
Quoted from fullcalendar website.
When specifying Event Objects for events or eventSources, you may
specify a string in IETF format (ex: "Wed, 18 Oct 2009 13:00:00 EST"),
a string in ISO8601 format (ex: "2009-11-05T13:15:30Z") or a UNIX
timestamp.
I am trying to build a ROR app that allows users to enter date in various formats such as 12/31/11 (month/day/year) or 31/12/11 (day/month/year). In order to interpret date format, I will have a select field from where user can select the format of date. I can use Date.strptime(value, format).to_s() in controller before saving record.
However, I am not sure is controller right place to put this information. Is there a way I can push this to model..say in before save method.
You could just save the data as it is (in the controller), and have another field in the model telling it how to interpret the data. Then, in a before_validation callback, you could try parsing the date according to the given format and writing it to the same field, now as a date. Problems may arise on the way back. Then, to display it in the view again, you could write helpers - but better yet, provide a method in the model (for instance, formatted_date) that will compute and display the date.
However, this requirement sounds strange. Why is the user's responsibility to select a date format? Shouldn't it be based on the user locale?
In any case, I suggest you register your date formats in an initializer, rather than repeting the format strings throughout the application.