admin管理员组文章数量:1026989
I've got a UTC date through an Ajax call, e.g. "/Date(1517216466000+0100)/"
,
which is when printing to the console: Mon Jan 29 2018 10:01:06 GMT+0100 (W. Europe Standard Time)
.
What I need to do, is to let the user change the timezones: I can easily do it with e.g. moment(myDate).tz("Japan")
.
Then I need to save the date in it's UTC format, which I am not able to do.
I've been experimenting with moment.utc()
, but for the input above, it returns 1 hour less.
How to deal with this situation? In summary:
1. Get a UTC time from a webservice
2. Let the user change the timezones
3. Save the modified date in UTC (without the timezone)
Working demo: ponent.html
EDIT for clarification:
Let's just have a look at the hours. What I get the date from the WCF, is 10 o'clock. The browser interprets it as 10 o'clock BUT in GMT+1 so when I convert it to UTC, it bees 9 o'clock.
I want it to be 10 o'clock as UTC. Then, if I modify the timezone and e.g. the minutes of this date, I want to be able to get the UTC value of this date.
EDIT2: Made my question simplier for clarification
I've got a UTC date, which I get from a webservice like: "/Date(1517216466000+0100)/" which is: Mon Jan 29 2018 10:01:06 GMT+0100 (W. Europe Standard Time) when printed to console.
I add a timezone to it with moment(this.inputDate).tz("Europe/Berlin").format(), but it stays 10:01:06, I guess because of my browsers GMT+1.
I want the ORIGINAL string to be used as a UTC date AND it should remain 10:01:06, not 09:01:06 as you can see above (2nd moment example), so with the timezone "Europe/Berlin" would be 11:01:6
I've got a UTC date through an Ajax call, e.g. "/Date(1517216466000+0100)/"
,
which is when printing to the console: Mon Jan 29 2018 10:01:06 GMT+0100 (W. Europe Standard Time)
.
What I need to do, is to let the user change the timezones: I can easily do it with e.g. moment(myDate).tz("Japan")
.
Then I need to save the date in it's UTC format, which I am not able to do.
I've been experimenting with moment.utc()
, but for the input above, it returns 1 hour less.
How to deal with this situation? In summary:
1. Get a UTC time from a webservice
2. Let the user change the timezones
3. Save the modified date in UTC (without the timezone)
Working demo: https://stackblitz./edit/angular-kqrct7?file=app%2Fapp.ponent.html
EDIT for clarification:
Let's just have a look at the hours. What I get the date from the WCF, is 10 o'clock. The browser interprets it as 10 o'clock BUT in GMT+1 so when I convert it to UTC, it bees 9 o'clock.
I want it to be 10 o'clock as UTC. Then, if I modify the timezone and e.g. the minutes of this date, I want to be able to get the UTC value of this date.
EDIT2: Made my question simplier for clarification
I've got a UTC date, which I get from a webservice like: "/Date(1517216466000+0100)/" which is: Mon Jan 29 2018 10:01:06 GMT+0100 (W. Europe Standard Time) when printed to console.
I add a timezone to it with moment(this.inputDate).tz("Europe/Berlin").format(), but it stays 10:01:06, I guess because of my browsers GMT+1.
I want the ORIGINAL string to be used as a UTC date AND it should remain 10:01:06, not 09:01:06 as you can see above (2nd moment example), so with the timezone "Europe/Berlin" would be 11:01:6
- Can you explain your problem using actual example values and show where it's going wrong. – phuzi Commented Jan 29, 2018 at 13:20
-
2
Save the modified date in UTC (without the timezone)
UTC has no timezone, that's the whole point. :) – Keith Commented Jan 29, 2018 at 13:21 - @Keith description updated – jeti Commented Jan 29, 2018 at 13:36
- @phuzi more details added – jeti Commented Jan 29, 2018 at 13:38
- Could you explain in simple terms what it is your trying to do..? Date/Time in Javascript can be a little bit confusing and you can end up over plicating things when not required. Basically all date-time's in Javascript visually work in locale time, but internally work in UTC, think of things this way might help. – Keith Commented Jan 29, 2018 at 13:50
3 Answers
Reset to default 4In the .NET JSON formatted date "/Date(1517216466000+0100)/" the timezone offset can be ignored. It represents "2018-01-29T09:01:06.000Z", where the source system was at a timezone offset of +0100. So if you don't care about the source timezone, just ignore it.
It is also an identical moment in time to Mon Jan 29 2018 10:01:06 GMT+0100 (W. Europe Standard Time), just with a different offset.
UTC is not a format, it's a time standard. If you want to use ISO 8601 format:
- Extract the first numeric value
- Convert to Number
- Pass to the Date constructor
- Call the toISOString method on the resulting Date
var s = '/Date(-1517216466000+0100)/';
console.log(new Date(+s.replace(/^[^\d-]+(-?\d+).*$/,'$1')).toISOString());
You can also parse and format it using moment.js, which according to the documentation can handle the .NET JSON format without needing to specify the format. So you can either do that or extract the time value and parse it with the "x" format token:
var s = '/Date(1517216466000+0100)/';
// Let moment.js guess the format
console.log(moment(s).utc());
// Extract time value and supply format
console.log(moment(s.replace(/^[^\d-]+(-?\d+).*$/,'$1'), 'x').utc());
<script src="https://cdnjs.cloudflare./ajax/libs/moment.js/2.20.1/moment.min.js"></script>
"/Date(1517216466000+0100)/"
is a non-standard way to serialise a date/time. Take a look at ISO8601 which defines several standard ways to represent dates and times.
That being said let's take a look at what this gets evaluated as...
moment("/Date(1517216466000+0100)/").toDate()
gives Mon Jan 29 2018 09:01:06 GMT+0000 (GMT Standard Time)
for me (in the UK)
taking just the timestamp value 1517216466000
new Date(1517216466000)
also gives Mon Jan 29 2018 09:01:06 GMT+0000 (GMT Standard Time)
this means that the +0100
is being ignored.
You're not actually modifying the time so why would you expect it to save back as anything other than Mon Jan 29 2018 09:01:06
UPDATE
But the "original" string represents Mon Jan 29 2018 09:01:06 UTC
the +0100
is ignored and it's just coincidence that your offset to UTC is also +0100
. An off.
Offset and timezone are 2 different things. A timezone enpasses offset to UTC as well as when/if daylight savings es in to force. Just because it says +0100 doesn't necessarily mean (W. Europe Standard Time) as it could just as easily be (West Africa Time) which is also UTC+0100 but doesn't observe daylight savings at all.
The time you have "/Date(1517216466000+0100)/"
doesn't convey enough information to say which timezone it is and JS/moment just uses the timestamp 1517216466000
and as such uses UTC. When you console.log()
this the browser writes it to screen as local time Mon Jan 29 2018 10:01:06 GMT+0100 (W. Europe Standard Time)
but this is only a representation of the underlying datetime.
By telling moment to use a specific time zone, it's only changing how the date/time gets displayed and doesn't actually change the time it represents.
If you use a date picker to change the date/time then you'll have to serialise the value to send to the backend in an appropriate way that the .Net app you cannot change will understand and conveys what you intend.
Example
- Get date from server as
var serverTime = "/Date(1517216466000+0100)/"
- convert this to a JS Date using moment
var time = new moment(serverTime)
- Let user specify TimeZone i.e. Japan Standard Time (UTC+9)
time = time.tz("Japan")
time
still representsMon Jan 29 2018 09:01:06 UTC
but when displayed on screen withtime.format()
gives"2018-01-29T18:01:06+09:00"
You stated "I want it to be 10 o'clock as UTC". Unfortunately the value you've is NOT 10 O'clock UTC and will never be 10 O'clock UTC because it isn't. It is 9 O'clock UTC
You could parse the value you get from the server yourself but the time from the server IS 9am UTC. If you change it to 10 am UTC then you would see that as Mon Jan 29 2018 11:01:06 GMT+0100 (W. Europe Standard Time)
- 11 O'clock local time.
Thanks everyone for your detailed answers, they helped me a lot in understanding my problem! However, the right solution was the following:
10 o'clock was a UTC time in the database and it got interpreted as 9 o'clock UTC in Moment.js because C# handled it as a local time. So, before sending the date to the client, I had to indicate that its a UTC:
var utcToClient = DateTime.SpecifyKind(downtime.DownTimeStartUTC, DateTimeKind.Utc)
Then, in Moment I could create a UTC with:
var jsUtc = moment.utc(downtime.DownTimeStartUTC)
Changing the timezones was a breeze with:
jsUtc.tz(userSelectedTimezone)
And saving the date in the database, I used this in C#:
var utcFromClient = Record.DownTimeStartUTC.ToUniversalTime()
I've got a UTC date through an Ajax call, e.g. "/Date(1517216466000+0100)/"
,
which is when printing to the console: Mon Jan 29 2018 10:01:06 GMT+0100 (W. Europe Standard Time)
.
What I need to do, is to let the user change the timezones: I can easily do it with e.g. moment(myDate).tz("Japan")
.
Then I need to save the date in it's UTC format, which I am not able to do.
I've been experimenting with moment.utc()
, but for the input above, it returns 1 hour less.
How to deal with this situation? In summary:
1. Get a UTC time from a webservice
2. Let the user change the timezones
3. Save the modified date in UTC (without the timezone)
Working demo: ponent.html
EDIT for clarification:
Let's just have a look at the hours. What I get the date from the WCF, is 10 o'clock. The browser interprets it as 10 o'clock BUT in GMT+1 so when I convert it to UTC, it bees 9 o'clock.
I want it to be 10 o'clock as UTC. Then, if I modify the timezone and e.g. the minutes of this date, I want to be able to get the UTC value of this date.
EDIT2: Made my question simplier for clarification
I've got a UTC date, which I get from a webservice like: "/Date(1517216466000+0100)/" which is: Mon Jan 29 2018 10:01:06 GMT+0100 (W. Europe Standard Time) when printed to console.
I add a timezone to it with moment(this.inputDate).tz("Europe/Berlin").format(), but it stays 10:01:06, I guess because of my browsers GMT+1.
I want the ORIGINAL string to be used as a UTC date AND it should remain 10:01:06, not 09:01:06 as you can see above (2nd moment example), so with the timezone "Europe/Berlin" would be 11:01:6
I've got a UTC date through an Ajax call, e.g. "/Date(1517216466000+0100)/"
,
which is when printing to the console: Mon Jan 29 2018 10:01:06 GMT+0100 (W. Europe Standard Time)
.
What I need to do, is to let the user change the timezones: I can easily do it with e.g. moment(myDate).tz("Japan")
.
Then I need to save the date in it's UTC format, which I am not able to do.
I've been experimenting with moment.utc()
, but for the input above, it returns 1 hour less.
How to deal with this situation? In summary:
1. Get a UTC time from a webservice
2. Let the user change the timezones
3. Save the modified date in UTC (without the timezone)
Working demo: https://stackblitz./edit/angular-kqrct7?file=app%2Fapp.ponent.html
EDIT for clarification:
Let's just have a look at the hours. What I get the date from the WCF, is 10 o'clock. The browser interprets it as 10 o'clock BUT in GMT+1 so when I convert it to UTC, it bees 9 o'clock.
I want it to be 10 o'clock as UTC. Then, if I modify the timezone and e.g. the minutes of this date, I want to be able to get the UTC value of this date.
EDIT2: Made my question simplier for clarification
I've got a UTC date, which I get from a webservice like: "/Date(1517216466000+0100)/" which is: Mon Jan 29 2018 10:01:06 GMT+0100 (W. Europe Standard Time) when printed to console.
I add a timezone to it with moment(this.inputDate).tz("Europe/Berlin").format(), but it stays 10:01:06, I guess because of my browsers GMT+1.
I want the ORIGINAL string to be used as a UTC date AND it should remain 10:01:06, not 09:01:06 as you can see above (2nd moment example), so with the timezone "Europe/Berlin" would be 11:01:6
- Can you explain your problem using actual example values and show where it's going wrong. – phuzi Commented Jan 29, 2018 at 13:20
-
2
Save the modified date in UTC (without the timezone)
UTC has no timezone, that's the whole point. :) – Keith Commented Jan 29, 2018 at 13:21 - @Keith description updated – jeti Commented Jan 29, 2018 at 13:36
- @phuzi more details added – jeti Commented Jan 29, 2018 at 13:38
- Could you explain in simple terms what it is your trying to do..? Date/Time in Javascript can be a little bit confusing and you can end up over plicating things when not required. Basically all date-time's in Javascript visually work in locale time, but internally work in UTC, think of things this way might help. – Keith Commented Jan 29, 2018 at 13:50
3 Answers
Reset to default 4In the .NET JSON formatted date "/Date(1517216466000+0100)/" the timezone offset can be ignored. It represents "2018-01-29T09:01:06.000Z", where the source system was at a timezone offset of +0100. So if you don't care about the source timezone, just ignore it.
It is also an identical moment in time to Mon Jan 29 2018 10:01:06 GMT+0100 (W. Europe Standard Time), just with a different offset.
UTC is not a format, it's a time standard. If you want to use ISO 8601 format:
- Extract the first numeric value
- Convert to Number
- Pass to the Date constructor
- Call the toISOString method on the resulting Date
var s = '/Date(-1517216466000+0100)/';
console.log(new Date(+s.replace(/^[^\d-]+(-?\d+).*$/,'$1')).toISOString());
You can also parse and format it using moment.js, which according to the documentation can handle the .NET JSON format without needing to specify the format. So you can either do that or extract the time value and parse it with the "x" format token:
var s = '/Date(1517216466000+0100)/';
// Let moment.js guess the format
console.log(moment(s).utc());
// Extract time value and supply format
console.log(moment(s.replace(/^[^\d-]+(-?\d+).*$/,'$1'), 'x').utc());
<script src="https://cdnjs.cloudflare./ajax/libs/moment.js/2.20.1/moment.min.js"></script>
"/Date(1517216466000+0100)/"
is a non-standard way to serialise a date/time. Take a look at ISO8601 which defines several standard ways to represent dates and times.
That being said let's take a look at what this gets evaluated as...
moment("/Date(1517216466000+0100)/").toDate()
gives Mon Jan 29 2018 09:01:06 GMT+0000 (GMT Standard Time)
for me (in the UK)
taking just the timestamp value 1517216466000
new Date(1517216466000)
also gives Mon Jan 29 2018 09:01:06 GMT+0000 (GMT Standard Time)
this means that the +0100
is being ignored.
You're not actually modifying the time so why would you expect it to save back as anything other than Mon Jan 29 2018 09:01:06
UPDATE
But the "original" string represents Mon Jan 29 2018 09:01:06 UTC
the +0100
is ignored and it's just coincidence that your offset to UTC is also +0100
. An off.
Offset and timezone are 2 different things. A timezone enpasses offset to UTC as well as when/if daylight savings es in to force. Just because it says +0100 doesn't necessarily mean (W. Europe Standard Time) as it could just as easily be (West Africa Time) which is also UTC+0100 but doesn't observe daylight savings at all.
The time you have "/Date(1517216466000+0100)/"
doesn't convey enough information to say which timezone it is and JS/moment just uses the timestamp 1517216466000
and as such uses UTC. When you console.log()
this the browser writes it to screen as local time Mon Jan 29 2018 10:01:06 GMT+0100 (W. Europe Standard Time)
but this is only a representation of the underlying datetime.
By telling moment to use a specific time zone, it's only changing how the date/time gets displayed and doesn't actually change the time it represents.
If you use a date picker to change the date/time then you'll have to serialise the value to send to the backend in an appropriate way that the .Net app you cannot change will understand and conveys what you intend.
Example
- Get date from server as
var serverTime = "/Date(1517216466000+0100)/"
- convert this to a JS Date using moment
var time = new moment(serverTime)
- Let user specify TimeZone i.e. Japan Standard Time (UTC+9)
time = time.tz("Japan")
time
still representsMon Jan 29 2018 09:01:06 UTC
but when displayed on screen withtime.format()
gives"2018-01-29T18:01:06+09:00"
You stated "I want it to be 10 o'clock as UTC". Unfortunately the value you've is NOT 10 O'clock UTC and will never be 10 O'clock UTC because it isn't. It is 9 O'clock UTC
You could parse the value you get from the server yourself but the time from the server IS 9am UTC. If you change it to 10 am UTC then you would see that as Mon Jan 29 2018 11:01:06 GMT+0100 (W. Europe Standard Time)
- 11 O'clock local time.
Thanks everyone for your detailed answers, they helped me a lot in understanding my problem! However, the right solution was the following:
10 o'clock was a UTC time in the database and it got interpreted as 9 o'clock UTC in Moment.js because C# handled it as a local time. So, before sending the date to the client, I had to indicate that its a UTC:
var utcToClient = DateTime.SpecifyKind(downtime.DownTimeStartUTC, DateTimeKind.Utc)
Then, in Moment I could create a UTC with:
var jsUtc = moment.utc(downtime.DownTimeStartUTC)
Changing the timezones was a breeze with:
jsUtc.tz(userSelectedTimezone)
And saving the date in the database, I used this in C#:
var utcFromClient = Record.DownTimeStartUTC.ToUniversalTime()
本文标签: javascriptNET dateMomentjsUTC and Timezone shiftingStack Overflow
版权声明:本文标题:javascript - .NET date, Moment.js, UTC and Timezone shifting - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1744853968a2120472.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论