# JavaScript Date 時間和日期
###### tags: `javaScript` `dateTime`
## 儲存時間的標準格式
> 時間是相對性的。
#### `timestamp` > 1481361366000,肉眼不好分辨。
- 表示從 1970-01-01 00:00:00 UTC (格林威治標準時間) 開始累計到某時間點的毫秒數 (milliseconds)
- 1593163158 這個 timestamp 代表的是:
「UTC +0 時區的 2020-06-26 09:19:00」,同時也代表著
「UTC +8 時區的 2020-06-26 17:19:00」,這兩個時間是一樣的,都是同一個時間。
- 所以當你拿到一個 timestamp 以後,你無法從 timestamp 本身知道你應該要顯示成什麼時區的時間。
#### `ISO 8601` > 2020-12-26T12:38:00Z 一種 date-time 格式
- 如果是 Z 就代表 UTC +0
- 如果要其他時區可以這樣寫:2020-12-26T12:38:00+08:00,代表 +8 時區的 12 月 26 號 12 點 38 分 0 秒。
<br />
## 建立特定時間點的 Date 物件
用 new Date(string) 就等於 Date.parse(string)
### 建立當前 date time object
> Date 物件參數的日期,預設的時區 (time zone) 是本地時區 (local time),也就是你瀏覽器作業系統設定的時區。
產生 GMT+8 時間的字串
```
const today = new Date();
// Sat Dec 10 2016 17:16:06 GMT+0800 (台北標準時間)
```
產生 ISO 8601 格式的字串 UTC+0
```
const today = new Date().toISOString();
// 2020-12-26T04:52:26.255Z
```
<br />
### 傳入 Timestamp 數字
> Timestamp >> 表示從 1970-01-01 00:00:00 UTC (格林威治標準時間) 開始累計到某時間點的毫秒數 (milliseconds)
```
new Date(timestamp);
const date = new Date(1481361366000);
// Sat Dec 10 2016 17:16:06 GMT+0800 (台北標準時間)
```
<br />
### 傳入 多個數字
> 傳入多個數字,指定年、月、日、時、分、秒、毫秒
> JavaScript 支援所有可以被 parse 的時間格式,詳細請看 parse() 方法的介紹。
```
new Date(year, month[, date[, hours[, minutes[, seconds[, milliseconds]]]]]);
var birthday = new Date(1995, 11, 17);
// Sun Dec 17 1995 00:00:00 GMT+0800 (CST)
```
- 月份 (month) >> 是從 0 到 11,0 是一月;11 是十二月。
- 時 (hours) >> 採 24 小時制
- 如果傳入的日期和時間參數超出正常範圍,例如月份輸入 13,秒數輸入 80,JavaScript 會自動增減做進位。
例如 >> new Date(2018, 13, 1) 會被看作是 new Date(2019, 1, 1);new Date(2016, 9, 10, 0, 80) 會被看作是 new Date(2016, 9, 10, 1, 20)。
<br />
<br />
## 轉換
### [ 取得 Timestamp & Unix Timestamp ]
#### 取得毫秒 Timestamp,有 4 種方法,回傳都一樣。
```
const miniGetTime = new Date().getTime();
const miniGetTime = +new Date();
const miniTime = Date.now();
```
使用 moment
```
// 當前 timestapm
const mm = moment().valueOf();
const mm = +moment();
// 指定時段轉換為 timestamp
const mm = moment('2016-01-01').valueOf();
```
<br />
#### 取得秒 Unix Timestamp
```
const dateTime = new Date().getTime();
const unixTimestamp = Math.floor(dateTime / 1000);
```
```
const dateTime = +new Date('2012-06-08');
const unixTimestamp = Math.floor(dateTime / 1000);
```
```
const dateTime = Date.now();
const unixTimestamp = Math.floor(dateTime / 1000);
```
使用 moment
```
// 當前 unix
const unixTimestamp = moment().unix();
// 指定時段轉換為 unix
const unixTimestamp = moment('2016-01-01').unix(); // 1451577600
```
<br />
### [ 轉換為 自定義時間格式 Format ]
#### Timestamp Format
```
const timestamp = 1624871919495;
const date = moment(timestamp).format('YYYY-MM-DD');
// '2021-06-28'
```
#### Unix Timestamp Format
```
const unixTimestamp = 1624871712;
const date = moment.unix(unixTimestamp).format('YYYY-MM-DD');
// '2021-06-28'
```
<br />
## 時區的顯示
如果沒有在 format 之前特別指定時區,format 出來的結果都會依照使用者當前的時區。所以同一段程式碼,在不同使用者的電腦可能會有不同的輸出。
例如:
```
luxon.DateTime
.fromISO('2020-02-02T13:00:00+03:00')
.toFormat('HH:mm:ss')
// 由於電腦是臺灣 +8 時區,所以結果會是 18:00:00 而不是 13:00:00
```
:::: info
因此 Server 端給你什麼都不重要,給你 `2020-02-02T13:00:00+03:00` 或是 `2020-02-02T10:00:00Z` 或 `2020-02-02T18:00:00+08:00`,對前端來說都是一樣的,都代表著同一個時間,用 format 也都會產生出一樣的結果。
::::
<br />
### [ 取得當地時區 Lacol time zone ]
`getTimezoneOffset()` 方法傳回當地時區與UTC時間的時區差,傳回的值是以`分鐘`為單位。以台灣來說,時區是UTC +8,傳回的值是-480。
Q: 到底是 GMT+8 還是 UTC+8 ? A: 現在的標準基本上都是 UTC 了
```
const tz = new Date().getTimezoneOffset();
// -480 ( -480/60 = -8 )
```
使用 moment
```
const tz = moment().utcOffset();
// 480
```
提供isLocal切換是否顯示當地時區,預設true,false則顯示+8時區
```
export const getTimezone = (isLocal = true) => {
return isLocal ? -(new Date().getTimezoneOffset() / 60) : 8;
};
```
##### 參考:
[淺談 JavaScript 中的時間與時區處理](https://blog.techbridge.cc/2020/12/26/javascript-date-time-and-timezone/)
[JavaScript Date 時間和日期](https://www.fooish.com/javascript/date/)