#244 邮件中的时间格式

2018-04-10

比如:

Sun, 20 Jun 2018 00:47:04 -0700 (PDT)
Thu, 10 Jun 2021 16:10:03 -0700 (PDT)
Thu, 10 Jun 2021 08:06:31 -0700 (PDT)

定义

定义在 RFC 822 的 5. DATE AND TIME SPECIFICATION

date-time   =  [ day "," ] date time        ; dd mm yy hh:mm:ss zzz
day         =  "Mon"  / "Tue" /  "Wed"  / "Thu" /  "Fri"  / "Sat" /  "Sun"
date        =  1*2DIGIT month 2DIGIT        ; day month year e.g. 20 Jun 82
month       =  "Jan"  /  "Feb" /  "Mar"  /  "Apr" /  "May"  /  "Jun" /  "Jul"  /  "Aug" /  "Sep"  /  "Oct" /  "Nov"  /  "Dec"
time        =  hour zone                    ; ANSI and Military
hour        =  2DIGIT ":" 2DIGIT [":" 2DIGIT]
                                            ; 00:00:00 - 23:59:59
zone        =  "UT"  / "GMT"                ; Universal Time
                                            ; North American : UT
            /  "EST" / "EDT"                ;  Eastern:  - 5/ - 4
            /  "CST" / "CDT"                ;  Central:  - 6/ - 5
            /  "MST" / "MDT"                ;  Mountain: - 7/ - 6
            /  "PST" / "PDT"                ;  Pacific:  - 8/ - 7
            /  1ALPHA                       ; Military: Z = UT;
                                            ;  A:-1; (J not used)
                                            ;  M:-12; N:+1; Y:+12
            / ( ("+" / "-") 4DIGIT )        ; Local differential
                                            ;  hours+min. (HHMM)

总结就是:

[day-of-week,] day month year hour:minute[:second] timezone
  1. 周几和秒是可选的,据我观察,没有邮件省略这两部分
  2. 周几和月份采用三字母英文缩写(首字母大写)
  3. 年份是 2 位数字,后来的规范更新中建议采用 4 位数字。出于兼容性考虑,一般都保留了对 RFC 822 两位数字年份的支持。
  4. 时区除了数字之外,可以使用 UTGMTESTEDTCSTCDTMSTMDTPSTPDT
    还有 25 个字母(J 没有使用),Z 表示 UTC/GMT 时间,A - M 表示 -1 ~ -12 时区,N - Y 表示 1 到 12 时区。
  1 2 3 4 5 6 7 8 9 10 11 12
West A B C D E F G H I K L M
Eest N O P Q R S T U V W X Y

Python

生成符合要求的时间字符串比较简单:

import time
time.strftime('%a, %d %b %Y %H:%M:%S %z')
# 'Tue, 10 Apr 2018 09:10:05 +0800'

但是由于这个灵活度比较大,解析起来最好借助专业的库(email.utils)来做这个事。

import time
import datetime
import email.utils
import pytz

# 解析 ############################################

date_str = 'Sun, 20 Jun 2018 00:47:04 -0700 (PDT)'
email.utils.parsedate_to_datetime(date_str)
# datetime.datetime(2018, 6, 20, 0, 47, 4, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=61200)))
email.utils.parsedate_tz(date_str)
(2018, 6, 20, 0, 47, 4, 0, 1, -1, -25200)

# 生成 ############################################

# email.utils.formatdate(timeval=None, localtime=False, usegmt=False)
email.utils.formatdate()
# 'Tue, 10 Apr 2018 09:10:41 -0000'

# email.utils.format_datetime(dt, usegmt=False)
dt = datetime.datetime.now()
email.utils.format_datetime(dt)
# 'Tue, 10 Apr 2018 09:16:43 -0000'

tz = pytz.timezone('Asia/Shanghai') # <DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>
dt = datetime.datetime(2018, 4, 10, 9, 10, 0, tzinfo=tz)
# datetime.datetime(2018, 4, 10, 9, 10, tzinfo=<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>)
email.utils.format_datetime(dt)
# 'Tue, 10 Apr 2018 09:10:00 +0806'

#243 邮箱地址的格式

2018-04-07

规范

规范定义比较复杂,甚至支持注释。

我简化一下(去掉注释,去掉双引号,去掉 [IPv4] / [IPv6] / 主机名 做域):

  1. 格式:域内部分@域
  2. 域内部分:

  3. 长度不超过 64

  4. 大小写字母 + 数字(62)
  5. ASCII 标点符号(19)

    !#$%&'*+-/=?^_`{|}~
    
  6. 可以加入点号(.)隔开,不放首尾,不连续出现

  7. 域名

  8. 每一级域名 1 - 63 个字符,总长度不超过 253
    这个限制和 DNS 报文设计有关
    国际化域名转换成 Punycode 之后也必须遵守这个约定

  9. 允许包含数字、字母(大小写不敏感)和短横线(-
  10. 短横线不能出现在首尾位置

实践

实际上的邮件地址会更加简单:

  1. 长度限制
  2. QQ 邮箱 3 - 18
  3. 网易邮箱 6 - 18
  4. Gmail 6 - 30
  5. 新浪邮箱 4 - 16
  6. 字符限制:字母数字 + .-_
  7. 一般大小写不敏感
  8. 连字符(.-_)不可连续出现
    1. 网易免费邮箱只支持下划线,网易 VIP 邮箱支持点和下划线
    2. Gmail 只支持点和加号
      1. 在实际投递中,点和加号会被忽略
      2. 点可以用作单词风格
      3. 加号通常用做来信归类,比如注册淘宝时 +taobao,订阅开发者头条时 +toutiao,相关邮件就方便搜索归类。
  9. 部分邮箱不支持全数字(别有用途,或是避免 QQ 号冲突,或是避免手机号冲突)
  10. 开头结尾字符限制:
    1. 字母数字开头 + 字母数字结尾
    2. 字母开头 / 字母数字结尾

正则表达式

以规范为准,参考真实场景下的实践:

域内部分:

/[a-z0-9]+([.-_#][a-z0-9]+)+/;

域名部分:

/[a-z0-9]+(-[a-z0-9]+)?(\.[a-z0-9]+(-[a-z0-9]+)?)+/;

汇总在一起就是:

/^[a-z0-9]+([.-_#][a-z0-9]+)+@[a-z0-9]+(-[a-z0-9]+)?(\.[a-z0-9]+(-[a-z0-9]+)?)+$/;

参考资料与拓展阅读

#242 OpenStack 相关网络技术

2018-03-24

相关文章:

物理设备

  1. VLAN 虚拟局域网,设备层面上的网络分区,网络设备提供的功能
    网络报文给 VLAN Tag 分配了四个字节,其中 3 个字节用于 VLAN ID,1 个字节用于 VLAN Priority。
    作为 VLAN ID 的 12bit(0-4095)中,首位两数作为保留值,也就是说 VLAN 技术支持的最大网络数是 4094。

Linux 网络技术

在 Linux 内核的网络设备管理层,虚拟设备和物理设备是同等地位。

  1. network namespace 网络隔离,虚拟化的基础
  2. bridge 网桥,相当于交换机,二层数据交换
  3. veth 虚拟网口,成对出现,两个虚拟网口之间可以相互连接(可以跨 namespace)
  4. tap/tun
  5. tap TAP 设备,虚拟二层网络,处理 TCP/UDP 包,
    有自己的 MAC 地址,可以桥接到物理网卡
  6. tun TUN 设备,虚拟三层网络,处理 IP 包
  7. iptables 网络管理
    确切的说是以 iptables 为代表的一系列网络管理技术

KVM / Neutron

  1. qvb neutron 网络桥
  2. qvo neutron 网络虚拟接口

Neutron 网络模式:

  1. VLAN
  2. VXLAN 虚拟拓展局域网,在三层 UDP 协议中封装二层数据包,突破 VLAN 的限制
  3. GRE Gerneral Routing Encapsulation,通用路由封装协议

#241 英语单词类别(词性)

2018-03-18
类别 英语名称 简写 说明
名词 noun n -
动词 verb v -
形容词 adjective adj -
副词 adverb ad/adv -
介词 preposition perp in on at
连词 conjunction conj and or but if
代词 pronoun pron I you he she
数词 numeral num one two three
冠词 article art the a an
感叹词 interjection interj oh hey
  • 名词:
    • 专有名词
    • 普通名词(可数/不可数);
      • 个体
      • 集体
      • 物质
      • 抽象
  • 冠词:不定冠词,定冠词,零冠词;
  • 数词:基数词,序数词;

#240 HTML alt 属性

2018-02-28

在 HTML 开发中,alt 是图片标签 <img> 的一个属性,表示图片的“替代文本(Alternative Text)”。
当图片无法正常加载时,alt 属性中的文本将作为替代内容显示出来。
此外,alt 属性还有助于提高网页的可访问性,因为屏幕阅读器会通过 alt 文本来帮助视障用户理解图片的内容。

举个例子

<img src="example.jpg" alt="风景优美的湖泊" />

当图片 example.jpg 无法加载时,用户会看到替代文本“风景优美的湖泊”。

  1. 就像上面说过的,alt 主要作用是提升可访问性
    由于网络文档,图片加载失败时,alt 属性可以传达一些信息(这个意义真的重要么?可以协助前端排查问题)。
    对于视障用户,屏幕阅读器会读取图片的 alt 属性,让他们知道图片的含义。这是建设无障碍网页的基础之一。

  2. SEO(搜索引擎优化) 帮助搜索引擎理解网页内容

注意点

简单明了(有利于解读页面内容(堆砌关键词真的有用吗?))
不要对页面内容累赘描述

工具

  • AI 生成器:https://ai-alttext.com/zh

#238 重力加速度

2018-02-03

基础认知

  • 速度单位:米每秒 $m/s$
  • 加速度单位:米每平方秒 $m/s^2$
    也等于牛顿每千克 $N/kg$
  • 重力加速度就是天体重力产生的加速度,符号 $g$
    有一个重力常数,符号是 $G$
  • 地表附近的重力加速度约为 9.81

重力引起的标准加速度(或自由落体的标准加速度),有时缩写为标准重力,通常用 $ɡ_0$ 或 $ɡ_n$ 表示,是物体在地球表面附近真空中的标称重力加速度。
标准定义为 $9.80665 m/s^2$(约 $32.17405 ft/s^2$)。
该值由第三届国际度量衡大会确定,用于将物体的标准重量定义为其质量和标称加速度的乘积。
地球表面附近物体的加速度是由于重力和地球自转的离心加速度的综合作用(但后者足够小,在大多数情况下可以忽略不计);
两极的总重力(视重力)比赤道高约百分之二。

参见:标准重力
https://en.wikipedia.org/wiki/Standard_gravity

运动

#237 shar: Shell Archive

2018-02-02
sudo apt install sharutils

提供四个命令:

  • shar: create a shell archive
  • unshar: unpack a shar archive
  • uudecode: decode an encoded file
  • uuencode: encode a file into email friendly text

uuencode 是一种二进制转文本编码,类似 Base64

没想到还有些包依赖这个上世纪遗留下来的编码(包括 gcc):

apt rdepends sharutils
sharutils
Reverse Depends:
  建议: file-roller
  依赖: wide-dhcpv6-client
  推荐: speechd-el
  建议: patool
  推荐: mgp
  建议: lxqt-archiver
  推荐: ldapscripts
  依赖: kpatch-build
  依赖: knews
  建议: git-dpm
  依赖: gcc-9-source
  依赖: gcc-12-source
  依赖: gcc-11-source
  依赖: gcc-10-source
  建议: engrampa
  依赖: biabam
  推荐: aespipe

python uuencode

import uu

uu.encode('/etc/passwd', '-')

注意:3.11 开始,python Deprecated 了这个 uu 模块, 可以改用 binascii.b2a_uu 代替。

import binascii

s = b''
with open('/etc/passwd', 'rb') as f:
    buf = f.read(45)
    while len(buf) > 0:
        s += binascii.b2a_uu(buf, backtick=False)
        buf = f.read(45)
print(s)