diff --git a/g/os/gtime/gtime_format.go b/g/os/gtime/gtime_format.go index 6d74e19a3..79e8dc807 100644 --- a/g/os/gtime/gtime_format.go +++ b/g/os/gtime/gtime_format.go @@ -10,6 +10,7 @@ import ( "bytes" "github.com/gogf/gf/g/text/gregex" "github.com/gogf/gf/g/text/gstr" + "strconv" "strings" ) @@ -20,8 +21,13 @@ var ( 'd': "02", // 月份中的第几天,有前导零的 2 位数字(01 到 31) 'D': "Mon", // 星期中的第几天,文本表示,3 个字母(Mon 到 Sun) 'w': "Monday", // 星期中的第几天,数字型式的文本表示 0为星期天 6为星期六 + 'W': "", // ISO-8601 格式年份中的第几周,每周从星期一开始 例如:42(当年的第 42 周) + 'N': "Monday", // ISO-8601 格式数字表示的星期中的第几天 1(表示星期一)到 7(表示星期天) 'j': "=j=02", // 月份中的第几天,没有前导零(1 到 31) + 'S': "02", // 每月天数后面的英文后缀,2 个字符 st,nd,rd 或者 th。可以和 j 一起用 'l': "Monday", // ("L"的小写字母)星期几,完整的文本格式(Sunday 到 Saturday) + 'z': "", // 年份中的第几天 0到365 + 't': "", // 指定的月份有几天 28到31 // ================== 月 ================== 'F': "January", // 月份,完整的文本格式,例如 January 或者 March January 到 December @@ -47,7 +53,7 @@ var ( // ================== 时区 ================== 'O': "-0700", // 与UTC相差的小时数, 例如:+0200 'P': "-07:00", // 与UTC的差别,小时和分钟之间有冒号分隔, 例如:+02:00 - 'T': "MST", // 时区缩写, 例如:UTC,GMT,CST + 'T': "MST", // 时区缩写, 例如: UTC, EST, MDT // ================== 完整的日期/时间 ================== 'c': "2006-01-02T15:04:05-07:00", // ISO 8601 格式的日期,例如:2004-02-12T15:19:21+00:00 @@ -64,6 +70,9 @@ var ( "Friday": "5", "Saturday": "6", } + + // 每个月累计的天数 不含润年的时候 + dayOfMonth = []int{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334} ) // 将自定义的格式转换为标准库时间格式 @@ -129,7 +138,12 @@ func (t *Time) Format(format string) string { } else { return buffer.String() } - + case 'W': + buffer.WriteString(strconv.Itoa(t.WeeksOfYear())) + case 'z': + buffer.WriteString(strconv.Itoa(t.DayOfYear())) + case 't': + buffer.WriteString(strconv.Itoa(t.DaysInMonth())) default: if runes[i] > 255 { buffer.WriteRune(runes[i]) @@ -147,6 +161,10 @@ func (t *Time) Format(format string) string { buffer.WriteString(strings.Replace(result, "=u=.", "", -1)) case 'w': buffer.WriteString(weekMap[result]) + case 'N': + buffer.WriteString(strings.Replace(weekMap[result], "0", "7", -1)) + case 'S': + buffer.WriteString(formatMonthDaySuffixMap(result)) default: buffer.WriteString(result) } @@ -159,7 +177,68 @@ func (t *Time) Format(format string) string { return buffer.String() } -// 格式化,使用标准库格式 +// 每月天数后面的英文后缀,2 个字符st nd,rd 或者 th +func formatMonthDaySuffixMap(day string) string { + switch day { + case "01": + return "st" + case "02": + return "nd" + case "03": + return "rd" + default: + return "th" + } +} + +// 返回是否是润年 +func (t *Time)IsLeapYear() bool { + year := t.Year() + if (year%4 == 0 && year%100 != 0) || year%400 == 0 { + return true + } + return false +} + +// 返回一个时间点在当年中是第几天 0到365 有润年情况 +func (t *Time)DayOfYear() int { + month := int(t.Month()) + day := t.Day() + + // 判断是否润年 + if t.IsLeapYear() { + if month > 2 { + return dayOfMonth[month-1] + day + } + return dayOfMonth[month-1] + day - 1 + } + return dayOfMonth[month-1] + day - 1 +} + +// 一个时间点所在的月最长有多少天 28至31 +func (t *Time)DaysInMonth() int { + month := int(t.Month()) + switch month { + case 1, 3, 5, 7, 8, 10, 12: + return 31 + case 4, 6, 9, 11: + return 30 + } + + // 只剩下第二月份,润年29天 + if t.IsLeapYear() { + return 29 + } + return 28 +} + +// 获取时间点在本年内是第多少周 +func (t *Time)WeeksOfYear() int { + _, nums := t.ISOWeek() + return nums +} + +// 格式化使用标准库格式 func (t *Time) Layout(layout string) string { return t.Time.Format(layout) } diff --git a/g/os/gtime/gtime_z_unit_format_test.go b/g/os/gtime/gtime_z_unit_format_test.go index 3d2028d29..6a67df146 100644 --- a/g/os/gtime/gtime_z_unit_format_test.go +++ b/g/os/gtime/gtime_z_unit_format_test.go @@ -45,9 +45,35 @@ func Test_Format(t *testing.T) { // 测试数字型的星期 times := []map[string]string{ {"k": "2019-04-22", "f": "w", "r": "1"}, + {"k": "2019-04-23", "f": "w", "r": "2"}, + {"k": "2019-04-24", "f": "w", "r": "3"}, + {"k": "2019-04-25", "f": "w", "r": "4"}, + {"k": "2019-04-26", "f": "dw", "r": "265"}, {"k": "2019-04-27", "f": "w", "r": "6"}, {"k": "2019-03-10", "f": "w", "r": "0"}, {"k": "2019-03-10", "f": "Y-m-d 星期:w", "r": "2019-03-10 星期:0"}, + {"k": "2019-04-25", "f": "N", "r": "4"}, + {"k": "2019-03-10", "f": "N", "r": "7"}, + {"k": "2019-03-01", "f": "S", "r": "st"}, + {"k": "2019-03-02", "f": "S", "r": "nd"}, + {"k": "2019-03-03", "f": "S", "r": "rd"}, + {"k": "2019-03-05", "f": "S", "r": "th"}, + + {"k": "2019-01-01", "f": "第z天", "r": "第0天"}, + {"k": "2019-01-05", "f": "第z天", "r": "第4天"}, + {"k": "2020-05-05", "f": "第z天", "r": "第125天"}, + {"k": "2020-12-31", "f": "第z天", "r": "第365天"}, //润年 + {"k": "2020-02-12", "f": "第z天", "r": "第42天"}, //润年 + {"k": "2019-02-12", "f": "有t天", "r": "有28天"}, + {"k": "2020-02-12", "f": "20.2有t天", "r": "20.2有29天"}, + {"k": "2019-03-12", "f": "19.3有t天", "r": "19.3有31天"}, + {"k": "2019-11-12", "f": "19.11有t天", "r": "19.11有30天"}, + {"k": "2019-01-01", "f": "第W周", "r": "第1周"}, + {"k": "2017-01-01", "f": "第W周", "r": "第52周"}, //星期7 + {"k": "2002-01-01", "f": "第W周为星期2", "r": "第1周为星期2"}, //星期2 + {"k": "2016-01-01", "f": "第W周为星期5", "r": "第53周为星期5"}, //星期5 + {"k": "2014-01-01", "f": "第W周为星期3", "r": "第1周为星期3"}, //星期3 + {"k": "2015-01-01", "f": "第W周为星期4", "r": "第1周为星期4"}, //星期4 } for _, v := range times { diff --git a/go.mod b/go.mod index 28729e4f6..fd3232e72 100644 --- a/go.mod +++ b/go.mod @@ -1,2 +1 @@ -module github.com/gogf/gf - +module github.com/gogf/gf \ No newline at end of file