最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

mongodb - How to the get the beginning of day of a date in javascript -- factoring in timezone - Stack Overflow

programmeradmin4浏览0评论

I am struggling to find out the beginning of day factoring in timezones in javascript. Consider the following:

   var raw_time = new Date(this.created_at);
   var offset_time = new Date(raw_hour.getTime() + time_zone_offset_in_ms);

   // This resets timezone to server timezone
   var offset_day = new Date(offset_time.setHours(0,0,0,0))
   // always returns 2011-12-08 05:00:00 UTC, no matter what the offset was!

   // This has the same issue:
   var another_approach_offset_day = new Date(offset_time.getFullYear(),offset_time.getMonth(),offset_time.getHours())

I expect when i pass a Pacific Timezone offset, to get: 2011-12-08 08:00:00 UTC and so on.

What is the correct way to achieve this?

I think that part of the issue is that setHours method sets the hour (from 0 to 23), according to local time.

Also note that I am using javascript embedded in mongo, so I am unable to use any additional libraries.

Thanks!


Jeez, so this was really hard for me, but here is the final solution that I came up with the following solution. The trick was I need to use setHours or SetUTCHours to get the beginning of a day -- the only choices I have are system time and UTC. So I get the beginning of a UTC day, then add back the offset!

// Goal is given a time and a timezone, find the beginning of day
function(timestamp,selected_timezone_offset) {
  var raw_time = new Date(timestamp)
  var offset_time = new Date(raw_time.getTime() + selected_timezone_offset);
  offset_time.setUTCHours(0,0,0,0);
  var beginning_of_day = new Date(offset_time.getTime() - selected_timezone_offset);
  return beginning_of_day;
}

I am struggling to find out the beginning of day factoring in timezones in javascript. Consider the following:

   var raw_time = new Date(this.created_at);
   var offset_time = new Date(raw_hour.getTime() + time_zone_offset_in_ms);

   // This resets timezone to server timezone
   var offset_day = new Date(offset_time.setHours(0,0,0,0))
   // always returns 2011-12-08 05:00:00 UTC, no matter what the offset was!

   // This has the same issue:
   var another_approach_offset_day = new Date(offset_time.getFullYear(),offset_time.getMonth(),offset_time.getHours())

I expect when i pass a Pacific Timezone offset, to get: 2011-12-08 08:00:00 UTC and so on.

What is the correct way to achieve this?

I think that part of the issue is that setHours method sets the hour (from 0 to 23), according to local time.

Also note that I am using javascript embedded in mongo, so I am unable to use any additional libraries.

Thanks!


Jeez, so this was really hard for me, but here is the final solution that I came up with the following solution. The trick was I need to use setHours or SetUTCHours to get the beginning of a day -- the only choices I have are system time and UTC. So I get the beginning of a UTC day, then add back the offset!

// Goal is given a time and a timezone, find the beginning of day
function(timestamp,selected_timezone_offset) {
  var raw_time = new Date(timestamp)
  var offset_time = new Date(raw_time.getTime() + selected_timezone_offset);
  offset_time.setUTCHours(0,0,0,0);
  var beginning_of_day = new Date(offset_time.getTime() - selected_timezone_offset);
  return beginning_of_day;
}
Share Improve this question edited Dec 12, 2011 at 16:26 Jonathan asked Dec 9, 2011 at 20:42 JonathanJonathan 16.4k12 gold badges73 silver badges110 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 5

In JavaScript all dates are stored as UTC. That is, the serial number returned by date.valueOf() is the number of milliseconds since 1970-01-01 00:00:00 UTC. But, when you examine a date via .toString() or .getHours(), etc., you get the value in local time. That is, the local time of the system running the script. You can get the value in UTC with methods like .toUTCString() or .getUTCHours(), etc.

So, you can't get a date in an arbitrary timezone, it's all UTC (or local). But, of course, you can get a string representation of a date in whatever timezone you like if you know the UTC offset. The easiest way would be to subtract the UTC offset from the date and call .getUTCHours() or .toUTCString() or whatever you need:

var d = new Date();
d.setMinutes(d.getMinutes() - 480); // get pacific standard time
d.toUTCString(); // returns "Fri, 9 Dec 2011 12:56:53 UTC"

Of course, you'll need to ignore that "UTC" at the end if you use .toUTCString(). You could just go:

d.toUTCString().replace(/UTC$/, "PST");

Edit: Don't worry about when timezones overlap date boundaries. If you pass setHours() a negative number, it will subtract those hours from midnight yesterday. Eg:

var d = new Date(2011, 11, 10, 15); // d represents Dec 10, 2011 at 3pm local time
d.setHours(-1);                     // d represents Dec 9, 2011 at 11pm local time
d.setHours(-24);                    // d represents Dec 8, 2011 at 12am local time
d.setHours(52);                     // d represents Dec 10, 2011 at 4am local time

Where does the time_zone_offset_in_ms variable you use e from? Perhaps it is unreliable, and you should be using Date's getTimezoneOffset() method. There is an example at the following URL:

http://www.w3schools./jsref/jsref_getTimezoneOffset.asp

If you know the date from a different date string you can do the following:

var currentDate = new Date(this.$picker.data('date'));
var today = new Date();
today.setHours(0, -currentDate.getTimezoneOffset(), 0, 0);

(based on the codebase for a project I did)

var aDate = new Date();
var startOfTheDay = new Date(aDate.getTime() - aDate.getTime() % 86400000)

Will create the beginning of the day, of the day in question

You can make use of Intl.DateTimeFormat. This is also how luxon handles timezones.

The code below can convert any date with any timezone to its beginging/end of the time.

const beginingOfDay = (options = {}) => {
  const { date = new Date(), timeZone } = options;
  const parts = Intl.DateTimeFormat("en-US", {
    timeZone,
    hourCycle: "h23",
    hour: "numeric",
    minute: "numeric",
    second: "numeric",
  }).formatToParts(date);
  const hour = parseInt(parts.find((i) => i.type === "hour").value);
  const minute = parseInt(parts.find((i) => i.type === "minute").value);
  const second = parseInt(parts.find((i) => i.type === "second").value);
  return new Date(
    1000 *
      Math.floor(
        (date - hour * 3600000 - minute * 60000 - second * 1000) / 1000
      )
  );
};

const endOfDay = (...args) =>
  new Date(beginingOfDay(...args).getTime() + 86399999);

const beginingOfYear = () => {};

console.log(beginingOfDay({ timeZone: "GMT" }));
console.log(endOfDay({ timeZone: "GMT" }));
console.log(beginingOfDay({ timeZone: "Asia/Tokyo" }));
console.log(endOfDay({ timeZone: "Asia/Tokyo" }));

发布评论

评论列表(0)

  1. 暂无评论