“The event is up and running, as expected, at 8 a.m. Yet the iPhone campaign hasn’t even started yet, and android has!” 🙀

Why hasn’t the event started yet? !

Let’s say an event is scheduled to start at 8am on December 25th, and apple users get to 8am and see the event button is still grey, and both PC and Android are working. If this happens, what is the first direction to consider?

New Date is passed to the UTC string:

new Date('2019-12-25T08:00')
// PC Chrome: Wed Dec 25 2019 08:00:00 GMT+0800
// apple Mobile: Wed Dec 25 2019 16:00:00 GMT+0800 (CST)
// mac safari: Wed Dec 25 2019 16:00:00 GMT+0800 (CST)
new Date('2019/12/25 08:00')
// PC Chrome: Wed Dec 25 2019 08:00:00 GMT+0800
// apple Mobile: Wed Dec 25 2019 08:00:00 GMT+0800 (CST)
// mac safari: Wed Dec 25 2019 08:00:00 GMT+0800 (CST)

// add a T and safari will count as a UTC string
Copy the code

Noon in Greenwich Mean time (GMT) is when the sun crosses the prime meridian (12 noon local time at GMT). With this reference point, time in any other time zone can be deduced. However, as we all know, the Earth is not a perfect sphere, and the earth’s rotation does not follow exactly the same rules every day. Today’s standard time is generally coordinated Universal Time (UTC), which is told by atomic clocks and is based on atomic time seconds. However, the GMT and UTC differences do not affect life.

We can also see that GMT+0800 (Chinese standard time) is printed on the new Date. China is marked GMT+0800 because it is located in the 8th East Zone, 8 hours away from UTC time. So 00:00:00 UTC, our time is 08:00:00. We can change GMT+0800 to GMT+0900. After the new Date, we find that one hour is lost. In addition, the CST printed on the mobile terminal represents Beijing time

All right, how to solve the above problem. We already know that there is a problem with transmitting UTC time, so we will not transmit UTC time.

Timestamps are good, but for historical reasons that are hard to change, what do you do if you’re given a UTC string?

First of all, putting a T in the middle separates the date and time, which on ios counts as a UTC string. If we want to solve the above problem, we can replace it with a space. If you execute new Date(‘2019-12-25 08:00’) on IOS, you will get the InvilAID Date. 2019-12-25 = 2019/12/25;

'2019-12-25T08:00'.replace(/-/g.'/').replace('T'.' ')
new Date('2019/12/25 08:00')
Copy the code

If you add a Z to the last digit, it must be UTC time, which is an extra 8 hours on a PC except ios

new Date('2019-12-25T08:00Z')
// PC: Wed Dec 25 2019 16:00:00 GMT+0800
Copy the code

In addition, Date.prototype also has a getTimezoneOffset. This method returns the time difference from UTC in minutes. We are at GMT+8 and return -480 (0-8) * 60 = -480

new Date().getTimezoneOffset()
Copy the code

So, we can use getTimezoneOffset as another solution to the above problem in UTC:

// Use this method when judging an Apple device
if (/iPhone|iPad|iPod|iOS/i.test(navigator.userAgent)) {
    const date = new Date(Date.parse(UTCString) + new Date().getTimezoneOffset() * 60 * 1000)}Copy the code

Continue to study

Get (UTC, GMT); get (UTC, GMT); The basic set and get methods, you’ve written a lot about date components, and there are mature solutions such as moment.

As for the time difference problem, if our products are not external, there is no problem generally. If it is UTC time, please remember to switch back. When it comes to overseas, we try to stick to UTC. For the front and back ends, the UTC time should also be passed, and the timestamp should be passed. UTC timestamp generation method

// Represents the UTC timestamp of 2019/12/11 11:11:11:011
Date.UTC(2019.11.11.11.11.11 ,11)
Copy the code

Now, let’s see how the two time conversion

Local time <=> UTC <=> Remote time

// Local remote uses UTC as the communication bridge
// Generate UTC locally/remotely
const UTCString = new Date().toISOString()
// Remote/local parse UTC
const dateString = new Date(UTCString) 
dateString.toLocaleString() // Formatted to local time, toLocaleString has many configuration items
Copy the code

UTC => Local/remote time

// An activity is centered around UTC time
const UTCTimestamp = Date.UTC(2019.11.11.11.11.11 ,11)
// Resolve to local time
const localTime = new Date(new Date(UTCTimestamp).toISOString())
/ / equivalent to the
new Date('2019-12-11T11:11:11Z') / / note -
// Format the time
localTime.toLocaleString()
Copy the code

Date prototype has a variety of toxxString, focusing on toLocaleString, toLocaleTime, they have a lot of parameter configuration items, the following summarized a wave of documentation, quickly familiar with the use of this method skills. Let’s start with a few examples:

// First, let's set a god time in UTC
const UTCTimestamp = Date.UTC(2019.11.11.11.11.11 ,11)
// None Default time format scheme of the current time zone
// 🇨🇳"2019/12/11 7:11:11 PM"
new Date(UTCTimestamp).toLocaleString()
new Date(UTCTimestamp).toLocaleString('zh-CN')

/ / 🇬 🇧 12/11/2019 7:11:11 PM
new Date(UTCTimestamp).toLocaleString('en-US')

// 🇫🇷 11/12/1919a 19:11:11
new Date(UTCTimestamp).toLocaleString('fr')

// 🇰🇷 2019. 12.11. 오 🇷 7:11:11
new Date(UTCTimestamp).toLocaleString('ko')
Copy the code

This representation takes an argument called the Locales argument, which specifies the local language and tells toLocaleString in which language and how to format the date. ToLocaleTimeString is the same, except that it only returns the time part.

ToLocaleString can also pass a second argument, which is a configuration object whose properties can be arbitrarily combined:

{['weekday'| (week)'era'(era)] :'narrow'(compact, the shortest) |'short'(short) |'long'(long),'year'|'month'|'day'|'hour'|'minute'|'second'] :'numeric'(complete) |'2-digit'(2A)}Month also supports "narrow", "short", and "long".
Copy the code

When used, the state of the key and its corresponding value is displayed in the date string returned. If the value of key is not specified, js will report an error

/ / 🌰
const date = new Date('2019-12-11T11:11:11Z')
date.toLocaleString("ch", {
  weekday: 'long'.year: 'numeric'.month: 'long'.day: 'numeric'.hour12: false.// The 12-hour mode is not enabled
  hour: '2-digit'.minute: '2-digit'.era: 'narrow'
})
// Wednesday, 11 December 2019 AD 19:11, what is the same for Chinese era

// All else being equal, change the language from ch to en
// options.era='narrow': Wednesday, December 11, 2019 A, 19:11
// options.era='short': Wednesday, December 11, 2019 AD, 19:11
// options.era='long': Wednesday, December 11, 2019 Anno Domini, 19:11
Hour12 =true: Wednesday, December 11, 2019 Anno Domini, 07:11 PM
Copy the code

Okay, there’s one more important property, timeZone, which determines the timeZone. So, if I give you a Date and you don’t specify the time zone, it will be whatever it is, and it won’t change the time zone. Everything we’ve done so far is the final demonstration of control. Its value must be in the timeZone database, which can be downloaded here.

Download the time zone data file, see a file named Asia, open it decisively, and find the relevant time zone of China:

date.toLocaleString("en", {
  weekday: 'long'.year: 'numeric'.month: 'long'.day: 'numeric'.hour12: true.hour: '2-digit'.minute: '2-digit'.era: 'long'.timeZone: 'Asia/Urumqi'
})
// Wednesday, December 11, 2019 Anno Domini, 05:11 PM Urumqi is two time zones short
// timeZone='Asia/Shanghai': Wednesday, December 11, 2019 Anno Domini, 07:11 PM
// timeZone='Europe/Vienna': Wednesday, December 11, 2019 Anno Domini, 12:11 PM
Copy the code

In fact, all kinds of attributes are free combination, play at will. So, do you think the date formatting is useless? That’s not true. What if it’s incompatible? However, it is also easy to detect toLocaleString incompatibility with various configurations passed in:

try {
    date.toLocaleString('are u ok? ')
    // Not compatible, implement a wave yourself
} catch {
    // Compatibility, fun
}

Copy the code

Intl is another option. MDN says: When formatting a large number of dates, it is best to create an Intl.dateTimeFormat object and then use the methods provided by the format attribute of that object. It’s pretty much the same thing to use

An implicit conversion to Date

Another previous article covered implicit conversions. Date objects are implicitly converted differently from other types. Date implicitly calls toString, while other types try to call valueOf first. If valueOf returns the same type, toString is executed.

new Date - 1 // timestamp - 1. ToString, find number type, valueOf. ValueOf of Date returns a timestamp
new Date + '1' // a string of characters 1. ToString, string + string, I don't have to do that anymore

// A magical result, guess: json.stringify will look for date's toJSON to use
new Date().toJSON() // "yyyy-mm-ddThh:mm:ss.mmmZ"
JSON.stringify(new Date) // ""yyyy-mm-ddThh:mm:ss.mmmZ""
// equivalent to json.stringify (" YYYY-MM-DDTHh :mm: ss.mmmz ")
Copy the code

Let’s boldly kill toJSON for Date:

const date = new Date
date.toJSON = null
JSON.stringify(date)
// "{"toJSON":null}"
Copy the code

You can change it to something else, and you end up with whatever it is, right

Pay attention to the public account “Different front-end”, learn front-end from a different perspective, grow fast, play with the latest technology, explore all kinds of black technology