#205 常见的时间格式

2017-07-24

日常使用

中国人习惯年月日时分秒,这可能也是一般符合国际通行规范的时间格式。

yymmdd
yyyymmdd
yyyy-mm-dd hh:mm:ss
yyyy/mm/dd hh:mm:ss

如果加上毫秒/微秒,在秒后面接上 ,SSS.SSS 就行。

但是由于英美的国际地位,以及由于历史原因而导致的英语的强势地位,英文国家的表述习惯也不能不考虑,

  • May 4, 1919 美式英语,读 may forth nineteen nineteen
  • 4 May, 1919 英式英语

用阿拉伯数字表示的话,可以用小数点、横杠、斜杠连接,数字可以用前导 0,
不过有一点很悲剧了,5/4/1919,如果不清楚上下文语境中的文化背景,谁 TM 知道应该算五四,还是四五。

Unix 时间戳

Unix Timestamp

又叫 Unix 时间(Unix Time),又叫 POSIX 时间(POSIX Time),又叫 Epoch Time。

以 UTC+0:00 1970/01/01 00:00:00 为起点,至今的秒数就是时间戳的值。

实际上我在很多项目中用到的时间戳都没有考虑时区,直接用当前系统默认时区的 1970/01/01 00:00:00 为起点,或者说是把当前时区时间当作零时区时间。

RFC2822

Internet Message Format, 邮件格式

date-time       =       [ day-of-week "," ] date FWS time [CFWS]
day-of-week     =       ([FWS] day-name) / obs-day-of-week
day-name        =       "Mon" / "Tue" / "Wed" / "Thu" /
                        "Fri" / "Sat" / "Sun"
date            =       day month year
year            =       4*DIGIT / obs-year
month           =       (FWS month-name FWS) / obs-month
month-name      =       "Jan" / "Feb" / "Mar" / "Apr" /
                        "May" / "Jun" / "Jul" / "Aug" /
                        "Sep" / "Oct" / "Nov" / "Dec"
day             =       ([FWS] 1*2DIGIT) / obs-day
time            =       time-of-day FWS zone
time-of-day     =       hour ":" minute [ ":" second ]
hour            =       2DIGIT / obs-hour
minute          =       2DIGIT / obs-minute
second          =       2DIGIT / obs-second
zone            =       (( "+" / "-" ) 4DIGIT) / obs-zone

1992/02/12 12:23:22+0800

Wed, 21 Jul 2017 10:35:00 +0000 (UTC)
Wed, 21 Jul 2017 18:35:19 +0800 (CST)
Wed, 21 Jul 2017 03:35:02 -0700 (PDT)
import time
import datetime

time.strftime('%a, %d %b %Y %H:%M:%S %z')  # local timezone
time.strftime('%a, %d %b %Y %H:%M:%S %z', time.gmtime())  # UTC

tz_e8 = datetime.timezone(datetime.timedelta(hours=8)) # +08:00
dt_e8 = datetime.datetime.now(tz_e8)
print(dt_e8)
print(dt_e8.strftime('%a, %d %b %Y %H:%M:%S %z'))

tz_w8 = datetime.timezone(datetime.timedelta(hours=-8)) # -08:00
dt_w8 = datetime.datetime.now(tz_w8)
print(dt_w8.strftime('%a, %d %b %Y %H:%M:%S %z'))

# dt_e8.strftime('%Y-%m-%d %H:%M:%S.%f')

ISO8601

约定了时间中各个部分的格式,比如年份应该采用四位数字,日期应该怎么表示,时间范围(比如一个月),循环时间,时间区间应该如何表示之类,是一份完整的时间相关规范。

对应的中国国家标准是 GB/T 7408-2005

比如我们要说的完整时间格式化就有几种允许的格式,下面就是常见的一种符合规范的表述:

YYYY-MM-DDThh:mm:ss+offset

例如:

2004-05-03T17:30:08Z
2004-05-03T17:30:08+08:00

其他

JavaScript 日期输出:

Sat Jul 24 2017 15:42:49 GMT+0800 (中国标准时间)

Python datatime 类型转字符串:

2017-07-25 12:09:39.123173+08:00

#202 纸张尺寸标准

2017-05-18

基本规则:

  1. 宽高比为 $\sqrt{2}$
  2. 精度为毫米(舍弃小数部分)

不同系列:

  1. A 系列:以面积为 1 平方米的纸张为 A0,每次于长边对切,分别得到 A1,A2...
  2. B 系列:宽边为 1 米的纸张编号 B0,,每次于长边对切,分别得到 B1,B2...
  3. C 系列:A 系列和 B 系列的几何平均,比如 C0 的尺寸是 $(\sqrt{W_{A0} \times W_{B0}}, \sqrt{H_{A0} \times H_{B0}})$
  4. 这样的话,C 系列尺寸介于 A,B 之间,A 系列纸张可以放入 C 系列同一编号的信封、文件袋中。

计算下来:

| Size |      A      |      B      |      C      |
|------|-------------|-------------|-------------|
|    0 |  841 × 1189 | 1000 × 1414 |  917 × 1297 |
|    1 |  594 ×  841 |  707 × 1000 |  648 ×  917 |
|    2 |  420 ×  594 |  500 ×  707 |  458 ×  648 |
|    3 |  297 ×  420 |  353 ×  500 |  324 ×  458 |
|    4 |  210 ×  297 |  250 ×  353 |  229 ×  324 |
|    5 |  148 ×  210 |  176 ×  250 |  162 ×  229 |
|    6 |  105 ×  148 |  125 ×  176 |  114 ×  162 |
|    7 |   74 ×  105 |   88 ×  125 |   81 ×  114 |
|    8 |   52 ×   74 |   62 ×   88 |   57 ×   81 |
|    9 |   37 ×   52 |   44 ×   62 |   40 ×   57 |
|   10 |   26 ×   37 |   31 ×   44 |   28 ×   40 |

国标

国标中没有定义 C 系列,但是有一个 D 系列,其尺寸定义的依据不明。
但我们经常在本子上看到的 16 开,32 开这样的字眼就从这里来的。

  1. 国标规定 D 系列原纸尺寸为 787mm x 1092mm
  2. $(W_{D1}, H_{D1}) = (\frac{H_{D0}}{2}, W_{D0} - 4)$
Series Size 称呼
D0 764 X 1064 全开
D1 532 X 760 半开
D2 380 X 528 4 开
D3 264 X 376 8 开
D4 188 X 260 16 开
D5 130 X 184 32 开
D6 92 X 126 64 开

北美标准(ANSI)

打印的时候经常可以看到。

#201 Linux 命名空间

2017-05-11

命名空间是什么

对内核资源进行分区,为进程隔离提供支持。

命名空间类型

Namespace CloneFlag Version Year
Mount (mnt) CLONE_NEWNS 2.4.19 2002
UTS CLONE_NEWUTS 2.6.19 2006
Inter-process Communication (ipc) CLONE_NEWIPC 2.6.19 2006
Process ID (pid) CLONE_NEWPID 2.6.24 2008
Network (net) CLONE_NEWNET 2.6.29 2009
User ID (user) CLONE_NEWUSER 3.8 2013
Control group (cgroup) CLONE_NEWCGROUP 4.6 2016
Time CLONE_NEWTIME 5.6 2020

Mount

挂载点可以在不同命名空间之间共享。

UTS

UNIX Time-Sharing

不知道为什么叫这个名字。作用是隔离主机名和域名。

IPC

不同 IPC 命名空间的进程不能通过 shm 系列方法共享内存。

PID

Network

每个网络命名空间都有一组自己的网络资源,包括 IP 地址、路由表、套接字列表、连接跟踪表、防火墙等等。

User

主要作用是权限的隔离。

Cgroup

进程控制组。

Time

时间的隔离。

系统调用

  • clone
  • unshare
  • setns

参考资料与拓展阅读

#200 Python 加密解密

2017-05-04

#199 英文花体

2017-04-27
| 𝓐 | 𝓑 | 𝓒 | 𝓓 | 𝓔 | 𝓕 | 𝓖 | | :-: | :-: | :-: | :-: | :-: | :-: | :----: | | 𝓗 | 𝓘 | 𝓙 | 𝓚 | 𝓛 | 𝓜 | 𝓝 | | 𝓞 | 𝓟 | 𝓠 | 𝓡 | 𝓢 | 𝓣 |   | | 𝓤 | 𝓥 | 𝓦 | 𝓧 | 𝓨 | 𝓩 |   | | 𝓪 | 𝓫 | 𝓬 | 𝓭 | 𝓮 | 𝓯 | 𝓰 | | 𝓱 | 𝓲 | 𝓳 | 𝓴 | 𝓵 | 𝓶 | 𝓷 | | 𝓸 | 𝓹 | 𝓺 | 𝓻 | 𝓼 | 𝓽 |   | | 𝓾 | 𝓿 | 𝔀 | 𝔁 | 𝔂 | 𝔃 |   |

#198 sdkman 的使用

2017-04-17
# 安装
curl -s "https://get.sdkman.io" | bash

# 查看当前版本
sdk version

# 更新到最新版本
sdk update

# 列出可用 Java 版本
sdk list java

# 安装指定 Java 版本
sdk install java 11.0.16-albba

# 切换到另一个已安装 Java 版本
sdk use java 8.8.9-albba

除了管理 Java 版本,还可以用来管理其他开发工具,比如 Gradle,Maven,Scale 等。

#197 惊群与 accept_mutex

2017-04-16

多个进程共享一个 bind socket 时,会发生这样的情况:一个连接进来,所有相关进程都从睡眠状态被唤醒。然后其中一个进程拿到这个连接,其他进程就继续 sleep。
这种现象就叫做惊群。好处就是如果来了大量连接的话,大家一起干活(可能可以算是正向的影响),坏处就是,如果只来了少量的连接,白白吵醒一众进程,消耗 CPU 资源。
这个好处像没有一样,资源的浪费确是实打实的。

注意,新版本 Nginx 上不需要互斥锁,默认没有惊群现象。

accept_mutex

Syntax: accept_mutex on | off;
Default: accept_mutex off;
Context: events

If accept_mutex is enabled, worker processes will accept new connections by turn. Otherwise, all worker processes will be notified about new connections, and if volume of new connections is low, some of the worker processes may just waste system resources.

There is no need to enable accept_mutex on systems that support the EPOLLEXCLUSIVE flag (1.11.3) or when using reuseport.

Prior to version 1.11.3, the default value was on.

如果 accept_mutex 启用,worker 进程会按顺序接受连接。否则,所有 worker 进程都会收到新连接通知,也就是惊群了。

1.11.3 之前,accept_mutex 默认是 on。为什么现在默认 off 了呢?
文档有写, 因为 1.11.3 之后,支持 EPOLLEXCLUSIVE 标记的平台,默认就不会发生惊群了,不需要 accept_mutex。

此外:如果使用了 TCP reuseport(需要 Linux 内核支持), 就不需要启用 accept_mutex。

如果 reuseport 参考: 2019/02/05, reuseport: 端口复用
PS: 2015/05 发布的 1.9.1 及之后版本,Nginx 引入了 reuseport 指令。

accept_mutex_delay

Syntax: accept_mutex_delay time;
Default: accept_mutex_delay 500ms;
Context: events

If accept_mutex is enabled, specifies the maximum time during which a worker process will try to restart accepting new connections if another worker process is currently accepting new connections.

如果 accept_mutex 启用,那么这个参数指定了 worker 进程申请 accept_mutex 锁失败之后的 sleep 时长。

也就是说如果出现竞争,没有抢到锁的进程就要睡眠一段时间,避免无效的反复申请锁。不过,感觉默认的这个 0.5 秒感觉有点长,50ms 应该就够了吧。

实现

参考:深入浅出 Linux 惊群:现象、原因和解决方案

附: 睡眠队列(等待队列)

#196 ASCII 码表

2017-04-15
Bin Oct Dec Hex 缩写/字符 解释
0000 0000 000 0 00 NUL(null) 空字符
0000 0001 001 1 01 SOH(start of headline) 标题开始
0000 0010 002 2 02 STX (start of text) 正文开始
0000 0011 003 3 03 ETX (end of text) 正文结束
0000 0100 004 4 04 EOT (end of transmission) 传输结束
0000 0101 005 5 05 ENQ (enquiry) 请求
0000 0110 006 6 06 ACK (acknowledge) 收到通知
0000 0111 007 7 07 BEL (bell) 响铃
0000 1000 010 8 08 BS (backspace) 退格
0000 1001 011 9 09 HT (horizontal tab) 水平制表符
0000 1010 012 10 0A LF (NL line feed, new line) 换行键
0000 1011 013 11 0B VT (vertical tab) 垂直制表符
0000 1100 014 12 0C FF (NP form feed, new page) 换页键
0000 1101 015 13 0D CR (carriage return) 回车键
0000 1110 016 14 0E SO (shift out) 不用切换
0000 1111 017 15 0F SI (shift in) 启用切换
0001 0000 020 16 10 DLE (data link escape) 数据链路转义
0001 0001 021 17 11 DC1 (device control 1) 设备控制 1
0001 0010 022 18 12 DC2 (device control 2) 设备控制 2
0001 0011 023 19 13 DC3 (device control 3) 设备控制 3
0001 0100 024 20 14 DC4 (device control 4) 设备控制 4
0001 0101 025 21 15 NAK (negative acknowledge) 拒绝接收
0001 0110 026 22 16 SYN (synchronous idle) 同步空闲
0001 0111 027 23 17 ETB (end of trans. block) 结束传输块
0001 1000 030 24 18 CAN (cancel) 取消
0001 1001 031 25 19 EM (end of medium) 媒介结束
0001 1010 032 26 1A SUB (substitute) 代替
0001 1011 033 27 1B ESC (escape) 换码(溢出)
0001 1100 034 28 1C FS (file separator) 文件分隔符
0001 1101 035 29 1D GS (group separator) 分组符
0001 1110 036 30 1E RS (record separator) 记录分隔符
0001 1111 037 31 1F US (unit separator) 单元分隔符
0010 0000 040 32 20 (space) 空格
0010 0001 041 33 21 ! 叹号
0010 0010 042 34 22 " 双引号
0010 0011 043 35 23 # 井号
0010 0100 044 36 24 $ 美元符
0010 0101 045 37 25 % 百分号
0010 0110 046 38 26 & 和号
0010 0111 047 39 27 ' 闭单引号
0010 1000 050 40 28 ( 开括号
0010 1001 051 41 29 ) 闭括号
0010 1010 052 42 2A * 星号
0010 1011 053 43 2B + 加号
0010 1100 054 44 2C , 逗号
0010 1101 055 45 2D - 减号/破折号
0010 1110 056 46 2E . 句号
0010 1111 057 47 2F / 斜杠
0011 0000 060 48 30 0 数字 0
0011 0001 061 49 31 1 数字 1
0011 0010 062 50 32 2 数字 2
0011 0011 063 51 33 3 数字 3
0011 0100 064 52 34 4 数字 4
0011 0101 065 53 35 5 数字 5
0011 0110 066 54 36 6 数字 6
0011 0111 067 55 37 7 数字 7
0011 1000 070 56 38 8 数字 8
0011 1001 071 57 39 9 数字 9
0011 1010 072 58 3A : 冒号
0011 1011 073 59 3B ; 分号
0011 1100 074 60 3C < 小于
0011 1101 075 61 3D = 等号
0011 1110 076 62 3E > 大于
0011 1111 077 63 3F ? 问号
0100 0000 100 64 40 @ 电子邮件符号
0100 0001 101 65 41 A 大写字母 A
0100 0010 102 66 42 B 大写字母 B
0100 0011 103 67 43 C 大写字母 C
0100 0100 104 68 44 D 大写字母 D
0100 0101 105 69 45 E 大写字母 E
0100 0110 106 70 46 F 大写字母 F
0100 0111 107 71 47 G 大写字母 G
0100 1000 110 72 48 H 大写字母 H
0100 1001 111 73 49 I 大写字母 I
0100 1010 112 74 4A J 大写字母 J
0100 1011 113 75 4B K 大写字母 K
0100 1100 114 76 4C L 大写字母 L
0100 1101 115 77 4D M 大写字母 M
0100 1110 116 78 4E N 大写字母 N
0100 1111 117 79 4F O 大写字母 O
0101 0000 120 80 50 P 大写字母 P
0101 0001 121 81 51 Q 大写字母 Q
0101 0010 122 82 52 R 大写字母 R
0101 0011 123 83 53 S 大写字母 S
0101 0100 124 84 54 T 大写字母 T
0101 0101 125 85 55 U 大写字母 U
0101 0110 126 86 56 V 大写字母 V
0101 0111 127 87 57 W 大写字母 W
0101 1000 130 88 58 X 大写字母 X
0101 1001 131 89 59 Y 大写字母 Y
0101 1010 132 90 5A Z 大写字母 Z
0101 1011 133 91 5B [ 开方括号
0101 1100 134 92 5C \ 反斜杠
0101 1101 135 93 5D ] 闭方括号
0101 1110 136 94 5E ^ 脱字符
0101 1111 137 95 5F _ 下划线
0110 0000 140 96 60 ` 开单引号
0110 0001 141 97 61 a 小写字母 a
0110 0010 142 98 62 b 小写字母 b
0110 0011 143 99 63 c 小写字母 c
0110 0100 144 100 64 d 小写字母 d
0110 0101 145 101 65 e 小写字母 e
0110 0110 146 102 66 f 小写字母 f
0110 0111 147 103 67 g 小写字母 g
0110 1000 150 104 68 h 小写字母 h
0110 1001 151 105 69 i 小写字母 i
0110 1010 152 106 6A j 小写字母 j
0110 1011 153 107 6B k 小写字母 k
0110 1100 154 108 6C l 小写字母 l
0110 1101 155 109 6D m 小写字母 m
0110 1110 156 110 6E n 小写字母 n
0110 1111 157 111 6F o 小写字母 o
0111 0000 160 112 70 p 小写字母 p
0111 0001 161 113 71 q 小写字母 q
0111 0010 162 114 72 r 小写字母 r
0111 0011 163 115 73 s 小写字母 s
0111 0100 164 116 74 t 小写字母 t
0111 0101 165 117 75 u 小写字母 u
0111 0110 166 118 76 v 小写字母 v
0111 0111 167 119 77 w 小写字母 w
0111 1000 170 120 78 x 小写字母 x
0111 1001 171 121 79 y 小写字母 y
0111 1010 172 122 7A z 小写字母 z
0111 1011 173 123 7B { 开花括号
0111 1100 174 124 7C | 垂线
0111 1101 175 125 7D } 闭花括号
0111 1110 176 126 7E ~ 波浪号
0111 1111 177 127 7F DEL (delete) 删除