0

I have utc date 2017-04-22T21:03:54 (local date is 2017-04-23 00:03:54, offset +3)

I would like to get data from server for 1 day. For this example, local day is:

start: 2017-04-23 00:00:00
end: 2017-04-23 23:59:59

And UTC params for server:

start: 2017-04-22 21:00:00
end: 2017-04-23 20:59:59

How I can receive this dates with moment.js? Local offset may be different

I try:

moment.utc(startTime).format() // 2017-04-22T21:03:54Z, but I need 2017-04-22T21:00:00Z
// for example, if local timezone will be +6, I need 2017-04-22T18:00:00Z
Max P
  • 1,439
  • 3
  • 15
  • 33
  • The UTC params for server should be [ISO 8601](http://stackoverflow.com/questions/25725019/how-do-i-format-a-date-as-iso-8601-in-moment-js) and the server code should parse them as ISO 8601. – Remus Rusanu Apr 29 '17 at 08:51
  • @RemusRusanu utc params for server - it's not problem. I can't understand, how I can convert UTC date to local with offset and make 24h start/end params. – Max P Apr 29 '17 at 08:54
  • 1
    1) your back end server should store all times in UTC to start with, there should be no conversion to local on server. 2) you never mention what your back end stack is. But parsing ISO and converting to local is straight forward in every language/library I know of. – Remus Rusanu Apr 29 '17 at 09:02
  • 1
    `moment.utc('2017-04-22T21:00:00Z').local().toDate()` – Remus Rusanu Apr 29 '17 at 09:22
  • @RemusRusanu local() is method what I looking for! Thank you. – Max P Apr 29 '17 at 12:41
  • @RemusRusanu—please don't answer in comments, it leaves the question unanswered and is not useful for others looking for an answer to the same question ([*Help Center > Answering*](http://stackoverflow.com/help/how-to-answer)). ;-) – RobG Apr 30 '17 at 02:34
  • @RemusRusanu ofc, at time when i finish issue, I put answer, or check suggested. – Max P Apr 30 '17 at 16:21

2 Answers2

1

I have utc date 2017-04-22T21:03:54

A date string without a time zone is treated as local (except for ISO 8601 date-only forms, which ECMAScript treats as UTC, contrary to ISO 8601). If you want to treat a string like "2017-04-22 21:00:00" as UTC then you have to tell the parser (in moment.js you can use the utc method).

You should also always tell the parser the format it's trying to parse, otherwise you're hoping it guesses correctly. If utc is used, moment uses offset +0000 by default (its "UTC mode" * ), not the local offset. If you want the host offset, you can use the local method or convert to a Date object and use built-in methods.

var s = '2017-04-22 21:00:00';
var format = 'YYYY-MM-DD HH:mm:ss';

// Tell parser to treat as UTC and the format
var m = moment.utc(s, format);

// Once the string has been parsed, you can output it in any format you like
console.log(
     'Original format, offset +0000 : ' + m.format(format)
  +'\nBuilt-in toISOString, offset Z: ' + m.toDate().toISOString()
  +'\nBuilt-in toString, host offset: ' + m.toDate().toString()
  +'\nOriginal format, host offset  : ' + m.local().format(format)
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

* I'm not sure this is a good idea as it means the code using the object needs to know it's in UTC mode. If you get a moment.js object from elsewhere, it would be good practice to set it to the "mode" you want. Calling local or utc multiple times has no bad effects.

RobG
  • 142,382
  • 31
  • 172
  • 209
1

(Putting my comments as answer)

  • The representation of datetimes in a text encoded transport/protocol (as HTTP) should follow ISO-8601. The time portion should include a timezone designator (for UTC time this is the simple Z, see link). These convention removes any ambiguity between client and server about what moment does the time literal represent.
  • Back ends should store times in UTC:
    • This removes any ambiguity when the database moves (failover to standby in different timezone, move of server to new location from east coast to west coats etc).
    • It removes any ambiguity for literals that fall into the DST time overlaps.
    • It removes any ambiguity from rushed legislative changes modifying timezones (of which several occur every few years)

Now that being said, if you need to convert an UTC time to local time in JavaScript/Node with MomentJS, use Moment's local().

Community
  • 1
  • 1
Remus Rusanu
  • 288,378
  • 40
  • 442
  • 569