---
# System prepended metadata

title: JavaScript Date 時間和日期
tags: [dateTime, javaScript]

---

# 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/)