This repository has been archived by the owner on Jun 7, 2024. It is now read-only.
forked from zsqk/deno-fn
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of github.com:zsqk/deno-fn
# Conflicts: # .github/workflows/deno.yml # deno/git.test.ts # deno/git.ts # deno/run.test.ts # deno/run.ts # js/aes.test.ts # js/date.test.ts # js/hash.benchmark.ts # js/hash.test.ts # js/hash.ts # js/lz-string.test.ts # js/str.test.ts # js/ua.test.ts
- Loading branch information
Showing
10 changed files
with
422 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// deno run -A tools/cli.ts | ||
import { parse } from 'https://deno.land/[email protected]/flags/mod.ts'; | ||
import { genGitPush } from "../deno/git.ts"; | ||
|
||
const args = parse< | ||
Partial< | ||
{ | ||
"repo-name": string; | ||
"repo-uri": string; | ||
"branch": string; | ||
"ssh": string; | ||
} | ||
> | ||
>( | ||
Deno.args, | ||
); | ||
|
||
const repoName = args['repo-name']; | ||
const repoURI = args['repo-uri']; | ||
const branch = args['branch']; | ||
const sshPrivateKey = args.ssh?.replaceAll("\\n", '\n'); | ||
|
||
if (!repoName || !repoURI || !sshPrivateKey) { | ||
console.error('args invalid') | ||
Deno.exit(1); | ||
} | ||
|
||
await genGitPush({ | ||
repoName, | ||
repoURI, | ||
branch, | ||
sshPrivateKey, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
"compilerOptions": { | ||
"strict": true | ||
}, | ||
"lock": false, | ||
"lint": { | ||
"files": { | ||
"include": [ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,12 @@ | |
// 结构化的时间到 ms | ||
// 渲染 ms 时间 (通过结构化) | ||
|
||
import { | ||
MillisecondTimestamp, | ||
MonthString, | ||
UnixTimestamp, | ||
} from '../ts/time.ts'; | ||
|
||
/** | ||
* 已被分析并且结构化的时间 | ||
*/ | ||
|
@@ -190,3 +196,252 @@ export function timeSummarize( | |
|
||
return ams; | ||
} | ||
|
||
/** | ||
* 获取月份 | ||
* @author iugo <[email protected]> | ||
*/ | ||
export function getMonths( | ||
/** 开始时间 (包含) */ | ||
startAt: UnixTimestamp, | ||
/** 结束时间 (包含) */ | ||
endAt: UnixTimestamp, | ||
opt: { timezone?: string } = {}, | ||
): { | ||
/** 月份, 202101 */ | ||
months: string[]; | ||
/** 之前的 不足一个月 */ | ||
before?: [UnixTimestamp, UnixTimestamp]; | ||
/** 之后的 不足一个月 */ | ||
after?: [UnixTimestamp, UnixTimestamp]; | ||
} { | ||
if (startAt > endAt) { | ||
throw new Error(`时间段选择有误, 开始时间不该大于结束时间`); | ||
} | ||
|
||
const months: string[] = []; | ||
/** 开始时间的毫秒时间戳 */ | ||
const startMillisecond = startAt * 1000; | ||
/** 结束时间的毫秒时间戳 */ | ||
const endMillisecond = endAt * 1000; | ||
/** 开始 Date */ | ||
const start = new Date(startMillisecond); | ||
/** 结束 Date */ | ||
const end = new Date(endMillisecond); | ||
/** 开始年份 */ | ||
let startYear = start.getFullYear(); | ||
/** 结束年份 */ | ||
let endYear = end.getFullYear(); | ||
/** 开始月份 */ | ||
let startMonth = start.getMonth() + 1; | ||
/** 结束月份 */ | ||
let endMonth = end.getMonth() + 1; | ||
|
||
// 如果在同一个月份, 则直接返回基础数值 | ||
if (startYear === endYear && startMonth === endMonth) { | ||
return { months: [], before: [startAt, endAt] }; | ||
} | ||
|
||
let before: [UnixTimestamp, UnixTimestamp] | undefined = undefined; | ||
if (startMillisecond !== getBeginningOfMonth(start, opt)) { | ||
before = [startAt, Math.trunc(getEndOfMonth(start, opt) / 1000)]; | ||
if (startMonth === 12) { | ||
startYear += 1; | ||
startMonth = 1; | ||
} else { | ||
startMonth += 1; | ||
} | ||
} | ||
|
||
let after: [UnixTimestamp, UnixTimestamp] | undefined = undefined; | ||
if (endMillisecond !== getEndOfMonth(end, opt)) { | ||
after = [Math.trunc(getBeginningOfMonth(end, opt) / 1000), endAt]; | ||
if (endMonth === 1) { | ||
endYear -= 1; | ||
endMonth = 12; | ||
} else { | ||
endMonth -= 1; | ||
} | ||
} | ||
|
||
// 如果没有一个完整的月 | ||
if (endYear < startYear || (startYear === endYear && endMonth < startMonth)) { | ||
return { months: [], before: [startAt, endAt] }; | ||
} | ||
|
||
// 特殊情况考虑完毕, 下面开始计算 months | ||
|
||
// 如果在同一年, 则只计算月差 | ||
if (startYear === endYear) { | ||
for (let m = startMonth; m <= endMonth; m++) { | ||
months.push(`${startYear}${m.toString().padStart(2, '0')}`); | ||
} | ||
} else { | ||
for (let m = startMonth; m <= 12; m++) { | ||
months.push(`${startYear}${m.toString().padStart(2, '0')}`); | ||
} | ||
for (let y = startYear + 1; y < endYear; y++) { | ||
months.push( | ||
`${y}01`, | ||
`${y}02`, | ||
`${y}03`, | ||
`${y}04`, | ||
`${y}05`, | ||
`${y}06`, | ||
`${y}07`, | ||
`${y}08`, | ||
`${y}09`, | ||
`${y}10`, | ||
`${y}11`, | ||
`${y}12`, | ||
); | ||
} | ||
for (let m = 1; m <= endMonth; m++) { | ||
months.push(`${endYear}${m.toString().padStart(2, '0')}`); | ||
} | ||
} | ||
|
||
// TODO: 如果不在同一年, 则计算开始与 12 的差, 结束与 1 的差 | ||
// TODO: 如果年差超过 1, 则附加 多出来年份的每一月 | ||
|
||
return { months, before, after }; | ||
} | ||
|
||
/** | ||
* 获取月末时间 | ||
* @param v 支持 Date 和 `202101...` 这样的字符串 | ||
* @returns 月末时间的毫秒时间戳 | ||
* @author iugo <[email protected]> | ||
*/ | ||
export function getEndOfMonth( | ||
v: Date | MonthString, | ||
opt: { timezone?: string } = {}, | ||
): MillisecondTimestamp { | ||
let d: Date; | ||
if (v instanceof Date) { | ||
d = v; | ||
} else if (typeof v === 'string') { | ||
let str = `${v.substring(0, 4)}/${v.substring(4, 6)}`; | ||
if (opt.timezone) { | ||
str += ' ' + opt.timezone; | ||
} | ||
d = new Date(str); | ||
} else { | ||
throw new TypeError('无效的参数类型'); | ||
} | ||
if (d.toString() === 'Invalid Date') { | ||
throw new Error('无效的时间'); | ||
} | ||
const y = d.getFullYear(); | ||
const m = d.getMonth() + 1; | ||
let key = m === 12 | ||
? `${y + 1}/01` | ||
: `${y}/${(m + 1).toString().padStart(2, '0')}`; | ||
if (opt.timezone) { | ||
key += ' ' + opt.timezone; | ||
} | ||
return new Date(key).getTime() - 1000; | ||
} | ||
|
||
/** | ||
* 获取月初时间 | ||
* @param v 支持 Date 和 `202101...` 这样的字符串 | ||
* @returns 月初时间的毫秒时间戳 | ||
* @author iugo <[email protected]> | ||
*/ | ||
export function getBeginningOfMonth( | ||
v: Date | MonthString, | ||
opt: { timezone?: string } = {}, | ||
): MillisecondTimestamp { | ||
let d: Date; | ||
if (v instanceof Date) { | ||
d = v; | ||
} else if (typeof v === 'string') { | ||
let str = `${v.substring(0, 4)}/${v.substring(4, 6)}`; | ||
if (opt.timezone) { | ||
str += ' ' + opt.timezone; | ||
} | ||
d = new Date(str); | ||
} else { | ||
throw new TypeError('无效的参数类型'); | ||
} | ||
if (d.toString() === 'Invalid Date') { | ||
throw new Error('无效的时间'); | ||
} | ||
const y = d.getFullYear(); | ||
const m = d.getMonth() + 1; | ||
let str = `${y}/${m.toString().padStart(2, '0')}`; | ||
if (opt.timezone) { | ||
str += ' ' + opt.timezone; | ||
} | ||
return new Date(str).getTime(); | ||
} | ||
|
||
/** | ||
* 获取 UNIX 时间戳 | ||
* @param v 毫秒时间戳, Date, 或者生成 Date 所需的字符串 | ||
* @returns | ||
*/ | ||
export function toUnixTimestamp( | ||
v: MillisecondTimestamp | Date | string = Date.now(), | ||
): UnixTimestamp { | ||
let t: number; | ||
if (typeof v === 'string') { | ||
t = new Date(v).getTime(); | ||
} else if (v instanceof Date) { | ||
t = v.getTime(); | ||
} else { | ||
t = v; | ||
} | ||
return Math.trunc(t / 1000); | ||
} | ||
|
||
/** | ||
* 解析 Date 对象的时间 | ||
* @param v 需要解析的时间, 默认为当前 | ||
* @param opt 参数 | ||
* @returns | ||
*/ | ||
export function parseDate( | ||
v: | ||
| Date | ||
| { unixMS: MillisecondTimestamp } | ||
| { unixS: UnixTimestamp } = new Date(), | ||
opt: { isUTC?: boolean } = {}, | ||
): { | ||
y: string; | ||
m: string; | ||
d: string; | ||
h: string; | ||
min: string; | ||
s: string; | ||
} { | ||
let date: Date; | ||
if ('unixMS' in v) { | ||
date = new Date(v.unixMS); | ||
} else if ('unixS' in v) { | ||
date = new Date(v.unixS * 1000); | ||
} else { | ||
date = v; | ||
} | ||
|
||
if (opt.isUTC) { | ||
const y = date.getUTCFullYear().toString(); | ||
const m = (date.getUTCMonth() + 1).toString().padStart(2, '0'); | ||
const d = date.getUTCDate().toString().padStart(2, '0'); | ||
const h = date.getUTCHours().toString().padStart(2, '0'); | ||
const min = date.getUTCMinutes().toString().padStart(2, '0'); | ||
const s = date.getUTCSeconds().toString().padStart(2, '0'); | ||
|
||
return { y, m, d, h, min, s }; | ||
} | ||
|
||
const y = date.getFullYear().toString(); | ||
const m = (date.getMonth() + 1).toString().padStart(2, '0'); | ||
const d = date.getDate().toString().padStart(2, '0'); | ||
const h = date.getHours().toString().padStart(2, '0'); | ||
const min = date.getMinutes().toString().padStart(2, '0'); | ||
const s = date.getSeconds().toString().padStart(2, '0'); | ||
|
||
return { y, m, d, h, min, s }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { assert } from 'https://deno.land/[email protected]/testing/asserts.ts'; | ||
import { checkIPv4 } from './ip.ts'; | ||
|
||
Deno.test('ipv4', () => { | ||
// 不允许无效的字符 | ||
assert(!checkIPv4('')); | ||
|
||
assert(!checkIPv4('a.a.a.a'), '不应该允许出现特殊字符'); | ||
|
||
assert(!checkIPv4('1.1.1.a'), '不应该允许出现特殊字符'); | ||
|
||
assert(!checkIPv4('1.1.1. 1'), '不应该允许出现特殊字符'); | ||
|
||
assert(!checkIPv4('300.1.1.1'), '不应该允许超位'); | ||
|
||
assert(!checkIPv4('1.1.1.1.1'), '不允许长度超长'); | ||
|
||
assert(checkIPv4('1.1.1.1')); | ||
}); |
Oops, something went wrong.