I'm wondering if it's possible to use AngularStrap's datepicker without it keeping the user's locale's timezone information. In our application we want to handle Contract objects that have an expiration date.
When adding or editing the contract object, there is a datepicker field for selecting the date. The following thing happens:
The user selects the date (e.g. 2013-10-24)
Angular binds the javascript date object to the ng-model field
The binded date object is in the user's timezone (e.g. GMT+3)
The user submits the form
The date gets sent to the server using Angular's $http service
In step 5 the date is converted to UTC format. The selected date was GMT+3 2013-10-24 at midnight, but the UTC conversion changes the date to 2013-10-23 at 9pm.
How could we prevent the conversion, or use UTC dates during the whole process? We don't want the contract's date to change based on the user's local timezone. Instead, we want the date to be always 2013-10-24, no matter what timezone.
Our current solution was to make small changes to the AngularStrap library so that the date won't change when sent to the server.
If we could get the user's selected timezone in the server, we could make another conversion there, but the server doesn't have that information.
All ideas are appreciated!
The issue isn't AngularStrap. Its just how javascript dates work and how JSON formats them for transmission. When you turn a javascript date object into a JSON string, it formats the string as UTC.
For example, I'm in Utah and it is now 07:41 on 2013-10-24. If I create a new javascript date and print it to the console it will say:
Thu Oct 24 2013 07:41:19 GMT-0600 (MDT)
If I stringify that same date (using JSON.stringify(date), I get:
"2013-10-24T13:41:47.656Z"
which you can see is not in my current timezone, but is in UTC. So the conversion is happening just before the form gets sent to the server when it gets converted from a javascript object to a JSON string.
The easiest way to do it would be to just change the date to a string of your own choosing prior to sending the date to the server. So instead of letting JSON change the date to UTC, (assuming you don't care about the time of day) you could just do something like this:
var dateStrToSend = $scope.date.getUTCFullYear() + '-' + ($scope.date.getUTCMonth() + 1) + '-' + $scope.date.getUTCDate();
That will give you a UTC-based string that looks like '2013-10-24' and then you can send that to the server, instead of the JSON format which includes the time info. Hopefully that helps.
UPDATE: As #Matt Johnson said, there are two ways to do it. You said: How could we prevent the conversion, or use UTC dates during the whole process?. If you want to use UTC, then use my above explanation. If you want to just "prevent the conversion", you could use the following:
var dateStrToSend = $scope.date.getFullYear() + '-' + ($scope.date.getMonth() + 1) + '-' + $scope.date.getDate();
A bit late but I spent my afternoon on this and someone might find it useful.
Another way to do this declaratively is to use the dateType, dateFormat and modelDateFormat attributes. Set these in either the config or the HTML e.g
angular.module('app').config(function ($datepickerProvider) {
angular.extend($datepickerProvider.defaults, {
dateFormat: 'dd-MMMM-yyyy',
modelDateFormat: "yyyy-MM-ddTHH:mm:ss",
dateType: "string"
});
});
DateFormat is the format the date will be displayed to the user in the date picker while modelDateFormat is the format it will be converted to before being bound to your model.
I also had default values coming from the server which I needed to be bound to the datepicker on page load. I therefore had to update the format the server serialized dates in JSON to match the modelDateFormat. I am using Web API so I used the below.
var jsonSettings = Formatters.JsonFormatter.SerializerSettings;
jsonSettings.DateFormatString = "yyyy-MM-ddTHH:mm:ss";
The "Angular way" is to use the $filter service to format the date returned by the datepicker.
Example (HTML):
{{inpDate | date: 'dd-MM-yyyy'}}
Example (JS):
$scope.processDate = function(dt) {
return $filter('date')(dt, 'dd-MM-yyyy');
}
Plunker here
Related
A web request gives me '2022-03-01'.
I know that is and always will mean UTC 2022-03-01 at midnight exactly.
I need to copy that value onto another CRM date field on the Form
I tried:
var passDateToLib = Date('2022-03-01')
formContext.getAttribute("new_otherdatefield").setValue(passDateToLib)
That new_otherdatefield field is also configured to be a UTC Date only field.
But what ends up shown in the field, is 1 date BEFORE '2022-03-01'. So I suspect it's ignoring the timezone aspect of the Date...
toISOString() gives the time in ISO format. To get the date only as you mentioned we can use substring method to remove the time. This will basically give the date based on GMT and not for your Local TimeZone.
new Date().toISOString().substring(0,10);
I would like to know whether the following is the right method to handle datetime data type in WebApi 2, Javascript and database.
DateTime from Javascript to WebApi:
var date = new Date();
var datestring = date.toISOString();
//Send datestring to WebApi
DateTime from WebApi to Javascript:
//on getting datetime value from `http.get` call
var dateFromServer = new Date(dateFromServer);
WebApi:
Incoming date
do nothing simply store the datestring returned in database column with datatype datetime
Getting date from database and Returning date to client:
no datetime manipulation (simply return as per WebApi Json serializer ex: 2015-10-23T18:30:00). Client would automatically convert the UTC datetime to local datetime
Yes if you don't want to handle any information about user Timezone etc... this is an acceptable way.
Just make sure that any time you want a date produced from the server for a comparison or something else to use the c# DateTime.UtcNow
method.
I think Having a "Global UTC Convention" its a quite safe and good solution but it has some limits.
For example if you want to Alert all of your users located in different timezones at 09:00 am (on each user's country) then its impossible to know when its "09:00" for each one.
One way to solve this(and it's the one i prefer), is to store manually each user's timezone info separately on the database, and every time you want to make a comparison simply convert the time.
TimeZoneInfo.ConvertTimeFromUtc(time, this.userTimezone);
Alternatively if you want to store all timezone information on the server you can :
Send your date from javascript to the server using the following format :
"2014-02-01T09:28:56.321-10:00" ISO 8601 also supports time zones by replacing the Z with + or – value for the timezone offset.
Declare your WEB API 2 Date types with the "DateTimeOffset" type.
Finally store your dates within the database using the "datetimeoffset" type.
This way any time on the server or the database you have all the information about the user's time and timezone.
You will find this article useful
I am having one website in which it has functionality to Login with specific timezone regardless what's the timezone on client side.
Now,
In website when user selects a date in dialog.I am sending it to server side using JSON.stringify with several other properties.
But whenever it is received at server side date is changed.
Example :-
I logged in using (+05 : 30) India time zone "01/08/2015 00:00:00" and server is having Casablanca Timezone.
When the date is received at server side the date is reduced by One "31/08/2015".
I think it is because of timezone conversion.
I already checked following link :-
JSON Stringify changes time of date because of UTC
I already tried that answer :- https://stackoverflow.com/a/1486612/2592727
But i am unable to understand how that formula works. So it's better to get more details and work with some specific solution.
Requirement :-
I am allowing user to select only date.
I want same date to be received over server side.
How can i accomplish this? Please describe with more details if possible.
Is there any simple way to avoid this collision?
The JSON.stringify method stored the date as UTC in the string, and when you parse that in .NET you will get a DateTime that contains the exact same point in time, but converted to the local time of the server.
You can handle this in two ways, you can either convert the time back to the original time zone, or you can avoid using the Date data type.
Converting to the original time zone of course requires you to know what the time zone is. Example:
var zone = TimeZoneInfo.FindSystemTimeZoneById("India Standard Time");
DateTime userTime = TimeZoneInfo.ConvertTimeFromUtc(date.ToUniversalTime(), zone);
To avoid using the Date type, you would format the date into a string before serialising it. Example:
var s = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate();
On the server side you would parse the string using the same format:
DateTime userTime = DateTime.ParseExact(date, "yyyy-M-d", CultureInfo.InvariantCulture);
Use the format yyyy-mm-dd hh:mm:ss and you will never get this ever again, regardless of timezone
In a nutshell I want moment to respect server's timezone. I've set my machine's timezone to Alaska but I'm passing a Brisbane timezone string to moment. Now I need moment.toDate to return a date instance in the same timezone as the one I pass in the moment constructor; e.g.
m = moment("2016-11-20T08:00:00+10:00")
m.format() // "2016-11-20T08:00:00+10:00"
m.toDate() // Sat Nov 19 2016 13:00:00 GMT-0900 (AKST)
I want to get a Date instance from moment that's in the input timezone; e.g. somehow get toDate to return Sun Nov 20 2016 08:00:00 GMT+1000 (AEST).
FWIW I have tried the same code with and without moment.tz.setDefault and while it correctly changes the format result, toDate always uses the machine's timezone!
Update
The reason I need this behaviour is that some JavaScript libraries and controls don't understand moment and only work with Date and the time/date gets skewed when presented back by them. One example, the one I'm currently dealing with, is jQuery UI date picker control. I want the date picker to show the current date as it's on the server (or on a specific timezone).
Thanks in advance.
The Date object represents the time in UTC internally, and can only use the time zone of the machine its running on when projected.
There's absolutely no way to produce a Date object that uses an arbitrary time zone. Any examples you may come across that try to manipulate the Date object (such by adding or subtracting time zone offsets) are fundamentally flawed.
Moment itself has great time zone support, including the moment-timezone extension for working with named time zones instead of just time zone offsets. But once you go back to a Date object - you're back at the mercy of the behavior of that object.
Sorry, but there's no way to achieve what you are asking. Perhaps you could elaborate as to why you wanted to do this, and I could recommend a workaround.
Update: With regards to your update, usually there is a mechanism for getting the value from a date picker as text, rather than as a date object. With the example of the jQuery UI date picker control, the onSelect event gives it to you as text already, or you can simply call .val() instead of .datepicker('getDate') to get the text out of the field. Once you have a textual value, you can then parse it with moment however you like.
Similarly, when setting the value, you don't necessarily need a Date object. You could just set the value of the textbox as a string, or you can pass a string to the setDate function.
In most cases, you won't have to go through a Date object. But if for some reason you do, then you'll need to artificially construct one with something crazy like:
var d = new Date(m.format('YYYY/MM/DD'));
Normally, I'd be against that - but if it's just there to get the pass a value to a UI control, then it's probably ok.
This will get you a moment in the same timezone as the moment string, but toDate is always in the local timezone.
d = "2016-11-20T08:00:00+10:00"
m = moment(d).utcOffset(d)
m.format()
m.toDate()
Good Day my fellow programmers,
I now have spent 2 days looking for a solution, and are about to go crazy..
That's the Problem:
On The WebPage, the User modifies an object, and i need to store the time without timezone info.
[ i just care about hours and minutes ]
the object is postet to the Server [ asp.net mvc 5] via ajax as a JsonResult.
Let's say, Server has Timezone UTC + 1 , User selects 09:00 on the webpage, json is ajax't to my controller, and boom - the resulting Object in my mvc controller has a DateTime Object with a time of 10:00 ;
What i have done: Client-side: Store Time Info in UTC Format [so a dateobjet.toUTCString() gives me the correct date i want to have, just before postig to the controller]
So is there a way to tell the JsonResult-Converter to just ignore the Timezone-Info and use the UTC-Time?
Thanks,
Mr.Muh
OK, i hope to describe it in a better (and shorter):
ClientSite: JavaScript date with the time i need in UTC (but still with some timezone information, which i don't need), let's say e.g. 'Fri, 01 Feb 1980 09:00:00 GMT' as a result from .toUTCString()
Get's wrapped up together with other variables in some Json & posted via ajax to my asp.net mvc 5 controller
ServerSide: Controller has my C# - Class as Argument (so automatically converting Json-Object to C# - Class), but the resulting DateTime part now says 10:00:00 due to my server TimeZone set to UTC+1.
So, How can i get the correct UTC time stored to my C# DateTime ?
Thanks :)
If I understand you correctly, you want to ignore the timezone. You can "reset" your DateTime object to UTC (without affecting the actual value) using DateTime.SpecifyKind:
DateTime utcTime = DateTime.SpecifyKind(originalDateTime, DateTimeKind.Utc);