Maximus Decimus
Maximus Decimus

Reputation: 5261

Get ISO string from a date without time zone

My configuration is Lisbon time zone. When I do new Date() I get my current local date/time which is Fri Apr 28 2017 01:10:55 GMT+0100 (GMT Daylight Time)

When I get the ISO string with toISOString() it will apply the time zone and I will get:

2017-04-28T00:10:55.964Z

The problem is that some minutes ago the date time was like this (yesterday):

2017-04-27T23:45:05.654Z

I tried moment.js (new to this) and I did something like this

document.write(moment('2017-04-28').format())

But I get this 2017-04-28T00:00:00+01:00 which is not 2017-04-28T00:00:00.000Z

I want to pass this value as a parameter of a restful method to parse it automatically as a DateTime type, but if I pass the output from moment.js format then it will get parsed as 2017-04-27 23:00:00.00

If I create a new date with new Date() or with new Date('2017-04-27') (date portion), I just want to get the ISO format like as follows with no time zone:

2017-04-28T00:00:00.000Z

Is there a javascript method like toISOString() or using maybe moment to get that format?

No matter what time zone or moment of day, I just to simulate that is midnight of the date given.

Upvotes: 61

Views: 180873

Answers (17)

M_Farahmand
M_Farahmand

Reputation: 1044

There is another tricky way you can use it, AFAIK from this answer. In Swedish date format you can convert your date easily to Iso format like below:

console.log(
  new Intl.DateTimeFormat('sv-SE').format(new Date())
)

Upvotes: 4

Daniil Yakavenka
Daniil Yakavenka

Reputation: 1

moment('2017-04-28').utcOffset(0, true).toISOString()

Upvotes: 0

Michal Bláha
Michal Bláha

Reputation: 11

Date formatting is not a main problem.
The whole question is based on a relatively wrong premise.

For a start it is necessary to realize what could be a Date.

First alternative is: "What time I see on my watches"
That is "relative date" because I see 11:00 at Europe at different time that somebody sees 11:00 at US

Second alternative is: "Point to specific moment in time"
That could be named "absolute date" and most important for this view is unix timestamp. The timestamp is ticking synchronously at whole world, although different people see different time at their watches.

So, 2017-04-28T00:10:55.964Z is equal to timestamp 1493338255 (btw Z in date string means: this is time at GMT). The same timestamp has 2017-04-28T01:10:55.964+01:00, 2017-04-28T09:10:55.964+09:00, 2017-04-27T16:10:55.964-08:00, etc.

That means: ISODateString says what time I see at my watches and how far away I am from Greenwich

And now implementation.
It is really important to say what do you need.

Let's have a set of hourly events.

Now guy from US coming and asking: "what happened yesterday?"
What should be at response?

There are 2 possibilities again:

  1. What happened during his day 2017-04-28T00:00:00-08:00 ... 2017-04-28T23:59:59-08:00
    It means 2017-04-28T08:00:00Z .. 2017-04-29T07:59:59Z and it is correct, because this is an actual day range of US people's

  2. What happened during calendar day 2017-04-28
    You can want some globally statistic and it is required to see the same at US as well as Japan.
    Solution is really simple - just drop time-shift -08:00 from question.
    moment('2017-04-28').format(YYYY-MM-DDTHH:mm:ss) should make something like this:
    2017-04-28T00:00:00 ... 2017-04-28T23:59:59

Just be careful, that is NOT an ISODateTime and you have to handle it right at the API!

Upvotes: 1

Abdulrahim Klis
Abdulrahim Klis

Reputation: 494

new Date('2019-04-27').toISOString();

also you can use dayjs: https://day.js.org/

Upvotes: 0

Rupesh Shingavi
Rupesh Shingavi

Reputation: 21

My issue: I need to send the date and time into ISO format to the server API all the time. To solve this issue, I could have simple used the new Date().toISOString() but my client app could be running under different time zone hence there would be time zone difference all the time.

Solution: To solve this issue, I referred the solution given above i.e. manually create the ISO format string regardless given time zone.

function getISOString(date)
{
let d = new Date(date),
month = '' + (d.getMonth() + 1),
day = '' + d.getDate(),
year = ''+ d.getFullYear(),
hours = ''+d.getHours(),
minutes = ''+d.getMinutes(),
seconds = ''+d.getSeconds();
month = month.length < 2? '0' + month : month;
day   = day.length < 2? '0' + day : day;
hours = hours.length < 2?'0'+hours:hours;
minutes = minutes.length< 2? '0'+minutes:minutes;
seconds = seconds.length< 2? '0'+seconds:seconds;
return ( [year, month, day].join('-')+'T'+[hours,minutes,seconds].join(':')+'.000');
}
console.log(getISOString(new Date()));

Upvotes: 2

yns Booster
yns Booster

Reputation: 121

you can try this, it works for me! you will have the ISO format without timeZone effect

Fri Jan 01 2021 23:10:00 GMT+0100 => 2021-01-01T23:10:00.000Z

function isoDateWithoutTimeZone(date) {
  if (date == null) return date;
  var timestamp = date.getTime() - date.getTimezoneOffset() * 60000;
  var correctDate = new Date(timestamp);
  // correctDate.setUTCHours(0, 0, 0, 0); // uncomment this if you want to remove the time
  return correctDate.toISOString();
}


        var now= new Date("01-01-2021 23:10:00");
        console.log(now.toString());
        var returnedDate = isoDateWithoutTimeZone(now);
        console.log(returnedDate);

Upvotes: 12

Dmitry Sikorsky
Dmitry Sikorsky

Reputation: 1501

I wrote a simple function that extends moment js objects:

moment.fn.toISOStringWithoutTimezone = function () {
  return this.format("YYYY-MM-DD[T]HH:mm:ss");
};

It can be used like

moment().toISOStringWithoutTimezone();

Upvotes: 2

Damien Minter
Damien Minter

Reputation: 359

old_date = Fri Jan 08 2021 16:01:30 GMT+0900

const new_date = old_date.toISOString().substring(0, 10);

new_date = "2021-01-08"

Upvotes: 22

Mike Gledhill
Mike Gledhill

Reputation: 29161

Here's two solutions for you....

Initially, I wrote a small piece of JavaScript (okay, okay, Typescript) which took a Date value and converted it into an ISO date string, like this:

createDateString(dateStr) {     
  //  Take a Date value, and turn it into a "2005-05-26T11:37:42" string
  var tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds
  var currentDate = new Date(dateStr);
  var withTimezone = new Date(currentDate.getTime() - tzoffset);
  var localISOTime = withTimezone.toISOString().slice(0, 19).replace('Z', '');
  return localISOTime;
}

This worked perfectly... until it was deployed onto a server. Then, I noticed that it was getting the timezone wrong.

My solution (without resorting to third-party products) was to rewrite it like this:

padZero(numericValue) {
  if (numericValue < 10)
      return '0' + numericValue.toString();;
     
  return numericValue.toString();;
}
createDateString(date) {     
  //  Take a Date value, and turn it into a "2005-05-26T11:37:42" string
  var dateStr = date.getFullYear() + '-' + 
        this.padZero(date.getMonth()+1) + '-' +
        this.padZero(date.getDate()) + 'T' +
        this.padZero(date.getHours()) + ':' + 
        this.padZero(date.getMinutes()) + ':' + 
        this.padZero(date.getSeconds());

  return dateStr;
}

Upvotes: 0

glneto
glneto

Reputation: 527

If you want the Date to be in UTC time (00:00:00) you can use:

moment.utc('2017-04-28').toISOString() // 2017-04-28T00:00:00.000Z

Upvotes: 0

Nambi N Rajan
Nambi N Rajan

Reputation: 509

From my understanding you want ISOString of start of the date irrespective of time

(ie) Time zone should be'T00:00:00.000Z' more matter what date you choose.

I dont think there is a straight function without using any plugin.

So i created a function to fullfill your need,If this is what you are looking for

function mimicISOString(date) {
    let d = new Date(date),
        month = '' + (d.getMonth() + 1),
        day = '' + d.getDate(),
        year = d.getFullYear();

    if (month.length < 2) 
        month = '0' + month;
    if (day.length < 2) 
        day = '0' + day;

    return [year, month, day].join('-') +'T00:00:00.000Z';
}

console.log(mimicISOString(new Date()));

This will return current date with start of the time zone.If this is what you are looking for

Upvotes: 1

Carlos Sanchez Correa
Carlos Sanchez Correa

Reputation: 11

You can use https://momentjs.com/docs/#/displaying/as-iso-string/

moment().toISOString(keepOffset);

Upvotes: 1

onmyway133
onmyway133

Reputation: 48085

You don't need moment.js library, you can just parse and connect date components. For example

type Components = {
  day: number,
  month: number,
  year: number
}

export default class DateFormatter {
  // 2018-11-11T00:00:00
  static ISOStringWithoutTimeZone = (date: Date): string => {
    const components = DateFormatter.format(DateFormatter.components(date))
    return `${components.year}-${components.month}-${components.day}T00:00:00`
  }

  static format = (components: Components) => {
    return {
      day: `${components.day}`.padStart(2, '0'),
      month: `${components.month}`.padStart(2, '0'),
      year: components.year
    }
  }

  static components = (date: Date): Components => {
    return {
      day: date.getDate(),
      month: date.getMonth() + 1,
      year: date.getFullYear()
    }
  }
}

Upvotes: 2

imjosh
imjosh

Reputation: 4872

I believe you are saying you'd like to get the current date in Lisbon:

moment().tz("Europe/Lisbon").format('YYYY-MM-DD')

You can see that this works the way you think it should:

moment('2017-04-28T00:00:00+01:00').tz("Europe/Lisbon").format('YYYY-MM-DD') //"2017-04-28"

Upvotes: -1

Smit
Smit

Reputation: 127

I suppose you wish to get the current date in ISO 8601 to pass it to your API? Maybe using a moment.js wrapper for native JavaScript mentioned here might help?

As in your example:

document.write(moment('01/12/2016', 'DD/MM/YYYY', true).toISOString());

Snippet:

$(function(){
  var displaysTime = $('#divTime');
  displaysTime.text(moment.utc('27/04/2017', 'DD/MM/YYYY', true).toISOString());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.5.1/moment.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>

<div id="divTime">
</div>

Upvotes: 0

RobG
RobG

Reputation: 147363

It's very unclear what you're asking. If you want the UTC date with the hours always 0, then set the UTC hours to 0 and use toISOString, e.g.

var d = new Date();
d.setUTCHours(0,0,0,0);
console.log(d.toISOString());

Of course this is going to show the UTC date, which may be different to the date on the system that generated the Date.

Also,

new Date('2017-04-27').toISOString();

should return 2017-04-27T00:00:00Z (i.e. it should be parsed as UTC according to ECMA-262, which is contrary to ISO 8601 which would treat it as local), however that is not reliable in all implementations in use.

If you just want to get the current date in ISO 8601 format, you can do:

if (!Date.prototype.toISODate) {
  Date.prototype.toISODate = function() {
    return this.getFullYear() + '-' +
           ('0'+ (this.getMonth()+1)).slice(-2) + '-' +
           ('0'+ this.getDate()).slice(-2);
  }
}

console.log(new Date().toISODate());

However, since the built-in toISOString uses UTC this might be confusing. If the UTC date is required, then:

if (!Date.prototype.toUTCDate) {
  Date.prototype.toUTCDate = function() {
    return this.getUTCFullYear() + '-' +
           ('0'+ (this.getUTCMonth()+1)).slice(-2) + '-' +
           ('0'+ this.getUTCDate()).slice(-2);
  }
}

console.log(new Date().toUTCDate());

Upvotes: 38

li x
li x

Reputation: 4051

You can achieve this by simply formating everything that you need in place using moment.format() and then simply append the extra Z to the string. You have to do this as Z within moment JS is reserved for outputting.

var date = moment('2014-08-28').format("YYYY-MM-DDT00:00:00.000") + "Z";

Fiddle example https://jsfiddle.net/2avxxz6q/

Upvotes: 19

Related Questions