目录
“千年虫”漏洞(Year 2000 Problem,简称“Y2K”)
计算机是怎么开始处理日期的么?
举例1:时间格式化举例( 过滤器)
举例2:时间格式化
自定义私有过滤器(日期格式化)
高性能计数器演示
OLE时间对象
时间的基本用法
“千年虫”漏洞(Year 2000 Problem,简称“Y2K”)
千年虫,又叫做“计算机2000年问题”、“电脑千禧年千年虫问题”或“千年危机”。缩写为“Y2K”。是指在某些使用了计算机程序的智能系统(包括计算机系统、自动控制芯片等)中,由于其中的年份只使用两位十进制数来表示,因此当系统进行(或涉及到)跨世纪的日期处理运算时(如多个日期之间的计算或比较等),就会出现错误的结果,进而引发各种各样的系统功能紊乱甚至崩溃。因此从根本上说千年虫是一种程序处理日期上的bug(计算机程序故障),而非病毒。
2000年新年前后,Y2K漏洞使得一些电子产品的计时系统出现故障。所以2022的漏洞被命名为“Y2K22”,后缀“22”即指2022年。
计算机是怎么开始处理日期的么?
关于计算机在时间上的处理 在 廖雪峰 Java 教程-日期和时间 讲得很好,有时间是伙伴可以详细看一下廖大佬的文章, 里面详细地表达了在计算机中如何表示日期和时间, 及 LocalDateTime ZonedDateTime DateTime DateTimeFormatter Instant Date和Calendar 等
举例1:时间格式化举例( 过滤器)
过滤器的概念
概念 :Vue.js 允许我们自定义过滤器,可被用作一些常见的文本格式化。过滤器可以用在两个地方:mustache 插值表达式 、 v-bind表达式 。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符指示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue2.5.16.js"></script>
</head>
<body>
<div id="app">
{{ time }}
<br/> {{ time | datefmt }}
</div>
<div id="app1">
{{ time | datefmt }}
</div>
</body>
<script>
// 定义一个名称为 datafmt的全局过滤器
Vue.filter('datefmt', function (input) {
// 过滤器的逻辑:将input的值格式化成 yyyy-MM-dd 字符串输出
var res = '';
var year = input.getFullYear();
var month = input.getMonth() + 1;
var day = input.getDate();
res = year + '-' + month + '-' + day;
return res;
});
new Vue({
el: '#app1',
data: {
time: new Date()
}
})
new Vue({
el: '#app',
data: {
time: new Date()
}
});
</script>
</html>
举例2:时间格式化
上面的举例1,时间格式化的过滤器,我们还有个更高端的写法:(字符串模板)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="vue2.5.16.js"></script>
</head>
<body>
<div id="app">
2018-05-25T14:06:51.618Z
<br /> {{ '2018-05-25T14:06:51.618Z' | dateFormat }}
</div>
</body>
<script>
Vue.filter('dateFormat', function (dateStr, pattern = "") {
// 根据给定的时间字符串,得到特定的时间
var dt = new Date(dateStr)
// yyyy-mm-dd
var y = dt.getFullYear()
var m = dt.getMonth() + 1
var d = dt.getDate()
// return y + '-' + m + '-' + d
if (pattern.toLowerCase() === 'yyyy-mm-dd') { //如果调用过滤器的参数写的是 yyyy-mm-dd,那就按照这种 yyyy-mm-dd 的格式写
//这里用的是字符串模板
return `${y}-${m}-${d}`
} else { //否则(比如说调用过滤器时不写参数),后面就补上 时-分-秒
var hh = dt.getHours()
var mm = dt.getMinutes()
var ss = dt.getSeconds()
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
}
})
new Vue({
el: '#app',
data: {
time: new Date()
}
});
</script>
</html>
运行结果:
举例2的改进:(字符串的padStart方法使用)
上图中,我们可以看到,箭头处的时间有些问题,比如说,`6`要写成`06`更合适。为了实现这个功能,我们可以这样做:
使用ES6中的字符串新方法 `String.prototype.padStart(maxLength, fillString='')` 或 `String.prototype.padEnd(maxLength, fillString='')`来填充字符串。 `pad`在英文中指的是`补充`。
实现举例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="vue2.5.16.js"></script>
</head>
<body>
<div id="app">
2018-05-25T14:06:51.618Z
<br /> {{ '2018-05-25T14:06:51.618Z' | dateFormat }}
</div>
</body>
<script>
Vue.filter('dateFormat', function (dateStr, pattern) {
// 根据给定的时间字符串,得到特定的时间
var dt = new Date(dateStr)
// yyyy-mm-dd
var y = dt.getFullYear()
var m = (dt.getMonth() + 1).toString().padStart(2, '0')
var d = dt.getDate().toString().padStart(2, '0')
if (pattern && pattern.toLowerCase() === 'yyyy-mm-dd') { //如果调用过滤器的参数写的是 yyyy-mm-dd,那就按照这种 yyyy-mm-dd 的格式写
//这里用的是字符串模板
return `${y}-${m}-${d}`
} else { //否则(比如说调用过滤器时不写参数),后面就补上 时-分-秒
var hh = dt.getHours().toString().padStart(2, '0')
var mm = dt.getMinutes().toString().padStart(2, '0')
var ss = dt.getSeconds().toString().padStart(2, '0')
return `${y}-${m}-${d} ${hh}:${mm}:${ss} ~~~~~~~`
}
})
new Vue({
el: '#app',
data: {
time: new Date()
}
});
</script>
</html>
运行结果:
`pattern`参数的解释:
在做`if (pattern && pattern.toLowerCase() === 'yyyy-mm-dd')`这个判断时,逻辑是:**先保证pattern参数传进来了,然后继续后面的判断**。
我们不能写成:`if (pattern.toLowerCase() === 'yyyy-mm-dd')`。因为,万一在调用的时候,不传递参数pattern,那么 if语句就相当于`if (undefined.toLowerCase() === 'yyyy-mm-dd')`,就会报错。
当然,ES6中有个新特性叫“默认参数”,我们就可以这样写:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="vue2.5.16.js"></script>
</head>
<body>
<div id="app">
2018-05-25T14:06:51.618Z
<br /> {{ '2018-05-25T14:06:51.618Z' | dateFormat }}
</div>
</body>
<script>
Vue.filter('dateFormat', function (dateStr, pattern = '') {
// 根据给定的时间字符串,得到特定的时间
var dt = new Date(dateStr)
// yyyy-mm-dd
var y = dt.getFullYear()
var m = (dt.getMonth() + 1).toString().padStart(2, '0')
var d = dt.getDate().toString().padStart(2, '0')
if (pattern.toLowerCase() === 'yyyy-mm-dd') { //如果调用过滤器的参数写的是 yyyy-mm-dd,那就按照这种 yyyy-mm-dd 的格式写
//这里用的是字符串模板
return `${y}-${m}-${d}`
} else { //否则(比如说调用过滤器时不写参数),后面就补上 时-分-秒
var hh = dt.getHours().toString().padStart(2, '0')
var mm = dt.getMinutes().toString().padStart(2, '0')
var ss = dt.getSeconds().toString().padStart(2, '0')
return `${y}-${m}-${d} ${hh}:${mm}:${ss} ~~~~~~~`
}
})
new Vue({
el: '#app',
data: {
time: new Date()
}
});
</script>
</html>
自定义私有过滤器(日期格式化)
私有过滤器:在某一个 vue 对象内部定义的过滤器称之为私有过滤器。这种过滤器只有在当前vue对象的el指定的监管区域有用。
举例:日期格式化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="vue2.5.16.js"></script>
</head>
<body>
<div id="app">
{{ time }}
<br />
{{ time | datefmt }}
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
time: new Date()
},
//在某一个vue对象内部定义的过滤器称之为私有过滤器,
//这种过滤器只有在当前vue对象el指定的监管的区域有用
filters: {
// input是自定义过滤器的默认参数,input的值永远都是取自于 | 左边的内容
datefmt: function (input) {
// 定义过滤器的内容:将input的值格式化成 yyyy-MM-dd 字符串输出
var res = '';
var year = input.getFullYear();
var month = input.getMonth() + 1;
var day = input.getDate();
res = year + '-' + month + '-' + day;
return res;
}
}
});
</script>
</html>
上面的代码中,我们在vue实例中,通过`filters`关键字,在里面定义了一个局部过滤器`datefmt`。
第一行代码显示的是默认的date。第二行代码显示的是格式化之后的date,说明过滤器是起到了作用的。
过滤器调用的时候,采用的是**就近原则**,如果私有过滤器和全局过滤器名称一致了,这时候 优先调用私有过滤器。
高性能计数器演示
import console;
import time.performance;
var tk = time.performance.tick();
sleep(2000)
console.log( ( time.performance.tick() - tk ) / 1000 ,"秒" );
console.pause();
OLE时间对象
//OLE时间对象
import console;
import time.ole;
//我们试一下创建一个OLE时间对象
var tm = time.ole();
//给他1970年以前的时间
tm.year = 1932;
//正确出现数值
console.log( tonumber( tm ) )
tm.year = 3010;//年
//再把他转换回来,仍然正确显示年份
console.log( time.ole( tonumber( tm ) ) )
//OLE时间支持系统格式化语法
var str = tostring(tm,"yyyy-MM-dd HH:mm:ss")
console.dump(str)
//也默认支持time对象的格式化语法
console.log(tostring(tm,"%Y年%m月%d日 %H时%M分%S秒"))
//还可以转换格式化语法
console.log( tm.toSystemFormat("%Y年%m月%d日 %H时%M分%S秒"))
//time对象也支持1900年到9999年之间的时间
var tm = time("1969/1/1 11:21:03","%Y/%m/%d %H:%M:%S")
console.log(tm)
//但是数值运行就不支持了
console.log( tonumber(tm) )
console.pause()
时间的基本用法
指定格式化时间
tm.format = "%a %B %Y %m %d %H:%M:%S";
tm.locale = "enu"; //整定格式化语言,无论指定什么语言,文本都必须是aardio默认的UTF8编码
console.log("时间格式化为字符串",tostring(tm));
在tostring中指定格式化参数
var str = tostring(tm,"%Y年%m月%d日 %H时%M分%S秒","chs")
console.log("时间格式化为简体中文",str);
使用格式串参数指定的规则重新将文本解析为时间对象, 不指定时间格式串时默认值为 '%Y/%m/%d %H:%M:%S',此格式串可兼容解析ISO8601格式时间
console.log( time("2017-05-27T16:56:01Z") )
使用格式串参数解析时间使用模糊匹配规则如下:
忽略日期时间首尾部不匹配字符,
一个空白字符可以匹配任意多个空白字符,一个标点可以匹配任意个连续的标点。
一个字母可以匹配任意个连续的字母,一个非ASCII字符可以匹配任意个连续的非ASCII字符。
多个不同的字段不能连接在一起,例如 12:04 不能写为 1204,中间应当有分隔符
var tm = time(str,"%Y年%m月%d日 %H时%M分%S秒","chs")
tm.year += 2;
console.log(tm,"增加2年")
tm.addsecond(30)
console.log(tm,"增加30秒")
tm.addminute(180)
console.log(tm,"增加180分")
tm.addhour(2)
console.log(tm,"增加两小时")
tm.addday(365)
console.log(tm,"增加365天")
tm.addmonth(-24)
console.log(tm,"倒退24个月")
var tm2 = time.now()
console.log( tm2.diffmonth(tm) ,"相差月份")
console.log( tm2.diffday(tm) ,"相差天数")
console.log( tm2.diffhour(tm) ,"相差小时数")
console.log( tm2.diffminute(tm) ,"相差分钟数")
console.log( tm2.diffsecond(tm) ,"相差秒数")
console.log( tonumber(tm) - tonumber(tm2) ,"相差秒数,作用同上")
console.log('\n关系运算符,相等、不等')
console.log( "tm2==tm", tm2 == tm )
console.log( "time.now()== time.now()", time.now()== time.now() )
console.log('\n关系运算符,大于、小于')
console.log( "tm2>tm", tm2 > tm )
console.log( "time.now() > time.now()", time.now() > time.now() )
console.log('\n关系运算符,大于等于、小于等于')
console.log( "tm2 <= tm", tm2 <= tm )
console.log( "time.now() <= time.now()", time.now() <= time.now() )
time.gmt() 创建一个time对象,并且设置HTTP协议协容的GMT时间格式,并将该对象的格式化语言设为英文
console.log( time.gmt() )
console.log( time.gmt( tm2.utc() ) ); //参数是其他time对象时,必须先转换为UTC时间
//HTTP时间RFC 1123格式,写错了空格这些自动修正
console.log(time.gmt("Sun,07Feb2016 081122 +7"))
//兼容HTTP时间RFC 850格式,星期写错了自动修正
console.log(time.gmt("Sunddddday, 07-Feb-16 08:11:22 +0700"))
//支持iso8601省略分隔符的格式
console.log(time.iso8601("20170822 123623 +0700"))
//支持iso8601省略分隔符的格式
console.log(time.iso8601("20170822 123623 +7"))
//兼容iso8601省略分隔符的写法
console.log(time("20170822 123623"))
console.pause()