JavaScript >> Javascript 文檔 >  >> Tags >> Date

JavaScript 日期格式

更新: 以下文檔已針對新的日期格式 1.2 進行了更新。立即獲取!

儘管 JavaScript 提供了許多方法來獲取和設置日期對象的一部分,但它缺乏一種根據用戶指定的掩碼來格式化日期和時間的簡單方法。有一些腳本提供了這個功能,但我從來沒有見過一個對我來說很好用的腳本……大多數都是不必要的笨重或緩慢,與不相關的功能聯繫在一起,使用或多或少需要你閱讀的複雜掩碼語法每次您想使用它們時都需要文檔,或者不考慮特殊情況,例如在生成的字符串中轉義掩碼字符。

在選擇用於我的 JavaScript 日期格式化程序的特殊掩碼字符時,我查看了 PHP 的日期函數和 ColdFusion 的離散 dateFormat 和 timeFormat 函數。 PHP 使用瘋狂的字母組合(至少對我來說,因為我不是 PHP 程序員)來表示各種日期實體,雖然我可能永遠不會記住完整的列表,但它確實提供了你可以同時應用的優點使用一個函數格式化日期和時間,並且沒有任何特殊字符重疊(與 ColdFusion 不同,其中 mmm 根據您處理的是日期還是時間,表示不同的東西)。另一方面,ColdFusion 使用非常容易記住的特殊字符作為掩碼。

使用我的日期格式化程序,我嘗試從兩者中獲取最好的功能,並添加一些我自己的糖。不過它確實很像 ColdFusion 實現,因為我主要使用 CF 的掩碼語法。

在進入更多細節之前,這裡有一些如何使用這個腳本的例子:

var now = new Date();

now.format("m/dd/yy");
// Returns, e.g., 6/09/07

// Can also be used as a standalone function
dateFormat(now, "dddd, mmmm dS, yyyy, h:MM:ss TT");
// Saturday, June 9th, 2007, 5:46:21 PM

// You can use one of several named masks
now.format("isoDateTime");
// 2007-06-09T17:46:21

// ...Or add your own
dateFormat.masks.hammerTime = 'HH:MM! "Can\'t touch this!"';
now.format("hammerTime");
// 17:46! Can't touch this!

// When using the standalone dateFormat function,
// you can also provide the date as a string
dateFormat("Jun 9 2007", "fullDate");
// Saturday, June 9, 2007

// Note that if you don't include the mask argument,
// dateFormat.masks.default is used
now.format();
// Sat Jun 09 2007 17:46:21

// And if you don't include the date argument,
// the current date and time is used
dateFormat();
// Sat Jun 09 2007 17:46:22

// You can also skip the date argument (as long as your mask doesn't
// contain any numbers), in which case the current date/time is used
dateFormat("longTime");
// 5:46:22 PM EST

// And finally, you can convert local time to UTC time. Either pass in
// true as an additional argument (no argument skipping allowed in this case):
dateFormat(now, "longTime", true);
now.format("longTime", true);
// Both lines return, e.g., 10:46:21 PM UTC

// ...Or add the prefix "UTC:" to your mask.
now.format("UTC:h:MM:ss TT Z");
// 10:46:21 PM UTC

以下是支持的特殊字符。與 ColdFusion 的 dateFormat 的任何含義差異 和 timeFormat 功能已註明。

掩碼 說明
d 以數字表示的月份中的日期;個位數天數沒有前導零。
dd 以數字表示的月份中的日期;個位數天的前導零。
ddd 星期幾的三個字母縮寫。
dddd 星期作為它的全名。
m 月份為數字;個位數月份沒有前導零。
mm 月份為數字;個位數月份的前導零。
mmm 月份的三個字母縮寫。
mmmm 月份作為它的全名。
yy 年份作為最後兩位數;小於 10 年的前導零。
yyyy 四位數字表示的年份。
h 小時;個位數小時(12 小時制)沒有前導零。
hh 小時;個位數小時(12 小時制)的前導零。
H 小時;個位數小時(24 小時制)沒有前導零。
HH 小時;個位數小時(24 小時制)的前導零。
M 分鐘;個位數分鐘沒有前導零。
大寫 M 與 CF timeFormat 不同 's m 以避免與月份發生衝突。
MM 分鐘;個位數分鐘的前導零。
大寫 MM 不同於 CF timeFormat 的 mm 以避免與月份發生衝突。
s 秒;個位數秒沒有前導零。
ss 秒;個位數秒的前導零。
l L 毫秒。 l 給出 3 位數。 L 給出 2 位數字。
t 小寫單字符時間標記字符串:ap .
CF 中沒有等價物。
tt 小寫,兩個字符的時間標記字符串:am下午 .
CF 中沒有等價物。
T 大寫,單字符時間標記字符串:AP .
大寫 T 與 CF 的 t 不同,允許用戶指定大小寫。
TT 大寫,兩個字符的時間標記字符串:AM下午 .
大寫 TT 與 CF 的 tt 不同,允許用戶指定大小寫。
Z 美國時區縮寫,例如美國東部標準時間MDT .對於非美國時區或在 Opera 瀏覽器中,將返回 GMT/UTC 偏移量,例如GMT-0500
CF 中沒有等價物。
o GMT/UTC 時區偏移量,例如-0500+0230 .
CF 中沒有等價物。
S 日期的序數後綴(st , , rd , 或第 )。適用於 d .
CF 中沒有等價物。
'…' "…" 文字字符序列。去除了周圍的引號。
CF 中沒有等效項。
UTC: 必須是掩碼的前四個字符。在應用掩碼之前將日期從本地時間轉換為 UTC/GMT/祖魯時間。 “UTC:”前綴已被移除。
CF 中沒有等效項。

以下是默認提供的命名掩碼(您可以輕鬆更改這些掩碼或添加您自己的掩碼):

名稱 面具 示例
默認 ddd mmm dd yyyy HH:MM:ss 2007 年 6 月 9 日星期六 17:46:21
shortDate 月/日/年 6/9/07
中日期 嗯 d, yyyy 2007 年 6 月 9 日
longDate mmmm d, yyyy 2007 年 6 月 9 日
fullDate dddd, mmmm d, yyyy 2007 年 6 月 9 日,星期六
短時間 h:MM TT 下午 5:46
中等時間 h:MM:ss TT 下午 5:46:21
longTime h:MM:ss TT Z 美國東部標準時間下午 5:46:21
isoDate yyyy-mm-dd 2007-06-09
isoTime HH:MM:ss 17:46:21
isoDateTime yyyy-mm-dd'T'HH:MM:ss 2007-06-09T17:46:21
isoUtcDateTime UTC:yyyy-mm-dd'T'HH:MM:ss'Z' 2007-06-09T22:46:21Z

幾個問題:

  • 萬一您的掩碼含義不明確(例如,m 後跟 mm ,沒有分隔字符),在您的元序列之間放置一對空引號。引號將被自動刪除。
  • 如果您需要在掩碼中包含文字引號,則適用以下規則:
    • 不成對的引號不需要特殊處理。
    • 要在包含任何其他相同類型引號的掩碼中包含文字引號,您需要用替代引號類型將它們括起來(即,單引號用雙引號,反之亦然)。例如,date.format('h "o\'clock, y\'all!"') 返回“6點鐘,你們”。這可能會有點毛茸茸,但我懷疑人們真的會經常遇到它。前面的例子也可以寫成date.format("h") + "o'clock, y'all!" .

代碼如下:

/*
 * Date Format 1.2.3
 * (c) 2007-2009 Steven Levithan <stevenlevithan.com>
 * MIT license
 *
 * Includes enhancements by Scott Trenda <scott.trenda.net>
 * and Kris Kowal <cixar.com/~kris.kowal/>
 *
 * Accepts a date, a mask, or a date and a mask.
 * Returns a formatted version of the given date.
 * The date defaults to the current date/time.
 * The mask defaults to dateFormat.masks.default.
 */

var dateFormat = function () {
	var	token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
		timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
		timezoneClip = /[^-+\dA-Z]/g,
		pad = function (val, len) {
			val = String(val);
			len = len || 2;
			while (val.length < len) val = "0" + val;
			return val;
		};

	// Regexes and supporting functions are cached through closure
	return function (date, mask, utc) {
		var dF = dateFormat;

		// You can't provide utc if you skip other args (use the "UTC:" mask prefix)
		if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) {
			mask = date;
			date = undefined;
		}

		// Passing date through Date applies Date.parse, if necessary
		date = date ? new Date(date) : new Date;
		if (isNaN(date)) throw SyntaxError("invalid date");

		mask = String(dF.masks[mask] || mask || dF.masks["default"]);

		// Allow setting the utc argument via the mask
		if (mask.slice(0, 4) == "UTC:") {
			mask = mask.slice(4);
			utc = true;
		}

		var	_ = utc ? "getUTC" : "get",
			d = date[_ + "Date"](),
			D = date[_ + "Day"](),
			m = date[_ + "Month"](),
			y = date[_ + "FullYear"](),
			H = date[_ + "Hours"](),
			M = date[_ + "Minutes"](),
			s = date[_ + "Seconds"](),
			L = date[_ + "Milliseconds"](),
			o = utc ? 0 : date.getTimezoneOffset(),
			flags = {
				d:    d,
				dd:   pad(d),
				ddd:  dF.i18n.dayNames[D],
				dddd: dF.i18n.dayNames[D + 7],
				m:    m + 1,
				mm:   pad(m + 1),
				mmm:  dF.i18n.monthNames[m],
				mmmm: dF.i18n.monthNames[m + 12],
				yy:   String(y).slice(2),
				yyyy: y,
				h:    H % 12 || 12,
				hh:   pad(H % 12 || 12),
				H:    H,
				HH:   pad(H),
				M:    M,
				MM:   pad(M),
				s:    s,
				ss:   pad(s),
				l:    pad(L, 3),
				L:    pad(L > 99 ? Math.round(L / 10) : L),
				t:    H < 12 ? "a"  : "p",
				tt:   H < 12 ? "am" : "pm",
				T:    H < 12 ? "A"  : "P",
				TT:   H < 12 ? "AM" : "PM",
				Z:    utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
				o:    (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
				S:    ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
			};

		return mask.replace(token, function ($0) {
			return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
		});
	};
}();

// Some common format strings
dateFormat.masks = {
	"default":      "ddd mmm dd yyyy HH:MM:ss",
	shortDate:      "m/d/yy",
	mediumDate:     "mmm d, yyyy",
	longDate:       "mmmm d, yyyy",
	fullDate:       "dddd, mmmm d, yyyy",
	shortTime:      "h:MM TT",
	mediumTime:     "h:MM:ss TT",
	longTime:       "h:MM:ss TT Z",
	isoDate:        "yyyy-mm-dd",
	isoTime:        "HH:MM:ss",
	isoDateTime:    "yyyy-mm-dd'T'HH:MM:ss",
	isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
};

// Internationalization strings
dateFormat.i18n = {
	dayNames: [
		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
		"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
	],
	monthNames: [
		"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
		"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
	]
};

// For convenience...
Date.prototype.format = function (mask, utc) {
	return dateFormat(this, mask, utc);
};

在這裡下載 (壓縮和壓縮後為 1.2 KB)。

請注意,可以通過更新 dateFormat.i18n 來更改日期和月份名稱(用於國際化或其他目的) 目的。

如果您有任何建議或發現任何問題,請告訴我。

想了解aphantasisa 和hyperphantasia、神韻邪教或揭穿邪教領袖Karen Zerby?查看我在 Life After Tech 上的新博客。


Tutorial JavaScript 教程
  1. Javascript 中的代理和反射 |第2部分

  2. 將 String.Replace() 與 RegEx 一起使用

  3. 通過 ID 查找數組對象並在 React 中返回

  4. 項目理念:終結時代的 RSS 閱讀器

  5. 如何在 Ionic 中對圖像和其他靜態資產進行指紋識別以進行緩存破壞?

  6. 使用沒有前端框架的組件

  7. 如何在客戶端創建和下載 xlsx?

  1. 全棧開發人員的 GraphQL 學習路徑

  2. 在 JavaScript 中將可迭代對象轉換為數組?

  3. 討厭 jQuery 不會讓你變酷

  4. 如何在 Firebase 上免費託管 React 或 Angular 應用程序

  5. React 表單庫應該解決的主要挑戰

  6. express-telescope:Expressjs 應用程序的漂亮錯誤頁面

  7. 我終於理解了函數即服務

  1. [ 教程 ] 使用 JavaScript 創建一個簡單的圖像輪播

  2. 僱用+加!對於員工,我是如何構建它的(UI - 工作)

  3. 從頭開始使用 NextJS 和样式化組件創建應用程序(第 3 部分)

  4. 使用 React Native 構建一個 Mini Instagram 克隆