"email.utils": 其他工具
***********************

**源代码:** Lib/email/utils.py

======================================================================

"email.utils" 模块提供如下几个工具

email.utils.localtime(dt=None)

   以感知型 datetime 对象返回当地时间。 如果调用时参数为空，则返回当前
   时间。 否则 *dt* 参数应该是一个 "datetime" 实例，并根据系统时区数据
   库转换为当地时区。 如果 *dt* 是简单型的 (即 "dt.tzinfo" 是 "None" )
   ，则假定为当地时间。 在这种情况下，为正值或零的 *isdst* 会使
   "localtime" 假定夏季时间（例如，夏令时）对指定时间生效或不生效。 负
   值 *isdst* 会使 "localtime" 预测夏季时间对指定时间是否生效。

   3.3 版新加入.

email.utils.make_msgid(idstring=None, domain=None)

   返回一个适合作为兼容 **RFC 2822** 的 *Message-ID* 标头的字符串。可
   选参数 *idstring* 可传入一字符串以增强该消息 ID 的唯一性。可选参数
   *domain* 可用于提供消息 ID 中字符 '@' 之后的部分，其默认值是本机的
   主机名。正常情况下无需覆盖此默认值，但在特定情况下覆盖默认值可能会
   有用，比如构建一个分布式系统，在多台主机上采用一致的域名。

   3.2 版更變: 增加了关键字 *domain*

下列函数是旧（"Compat32"）电子邮件 API 的一部分。新 API 提供的解析和格
式化在标头解析机制中已经被自动完成，故在使用新 API 时没有必要直接使用
它们函数。

email.utils.quote(str)

   返回一个新的字符串， *str* 中的反斜杠被替换为两个反斜杠，并且双引号
   被替换为反斜杠加双引号。

email.utils.unquote(str)

   返回 *str* 被去除引用后的字符串。如果 *str* 开头和结尾均是双引号，
   则这对双引号被去除。类似地，如果 *str* 开头和结尾都是尖角括号，这对
   尖角括号会被去除。

email.utils.parseaddr(address)

   将地址（应为诸如 *To* 或者 *Cc* 之类包含地址的字段值）解析为构成之
   的 *真实名字* 和 *电子邮件地址* 部分。返回包含这两个信息的一个元组
   ；如若解析失败，则返回一个二元组 "('', '')" 。

email.utils.formataddr(pair, charset='utf-8')

   是 "parseaddr()" 的逆操作，接受一个 "(真实名字, 电子邮件地址)" 的二
   元组，并返回适合于 *To* or *Cc* 标头的字符串。如果第一个元素为假性
   值，则第二个元素将被原样返回。

   可选地，如果指定 *charset*，则被视为一符合 **RFC 2047** 的编码字符
   集，用于编码 "真实名字" 中的非 ASCII 字符。可以是一个 "str" 类的实
   例，或者一个 "Charset" 类。默认为  "utf-8" 。

   3.3 版更變: 添加了 *charset* 选项。

email.utils.getaddresses(fieldvalues)

   该方法返回一个形似 "parseaddr()" 返回的二元组的列表。 *fieldvalues*
   是一个序列，包含了形似 "Message.get_all" 返回值的标头字段值。获取了
   一消息的所有收件人的简单示例如下：

      from email.utils import getaddresses

      tos = msg.get_all('to', [])
      ccs = msg.get_all('cc', [])
      resent_tos = msg.get_all('resent-to', [])
      resent_ccs = msg.get_all('resent-cc', [])
      all_recipients = getaddresses(tos + ccs + resent_tos + resent_ccs)

email.utils.parsedate(date)

   尝试根据 **RFC 2822** 的规则解析一个日期。然而，有些寄信人不严格遵
   守这一格式，所以这种情况下 "parsedate()" 会尝试猜测其形式。*date*
   是一个字符串包含了一个形如 ""Mon, 20 Nov 1995 19:12:08 -0500"" 的
   **RFC 2822** 格式日期。如果日期解析成功， "parsedate()" 将返回一个
   九元组，可直接传递给 "time.mktime()"；否则返回 "None"。注意返回的元
   组中下标为 6、7、8 的部分是无用的。

email.utils.parsedate_tz(date)

   Performs the same function as "parsedate()", but returns either
   "None" or a 10-tuple; the first 9 elements make up a tuple that can
   be passed directly to "time.mktime()", and the tenth is the offset
   of the date's timezone from UTC (which is the official term for
   Greenwich Mean Time) [1].  If the input string has no timezone, the
   last element of the tuple returned is "0", which represents UTC.
   Note that indexes 6, 7, and 8 of the result tuple are not usable.

email.utils.parsedate_to_datetime(date)

   "format_datetime()" 的逆操作。 执行与 "parsedate()" 相同的功能，但
   会在成功时返回一个 "datetime"。 如果输入日期的时区值为 "-0000"，则
   "datetime" 将为一个简单型 "datetime"，而如果日期符合 RFC 标准则它将
   代表一个 UTC 时间，但是并不指明日期所在消息的实际源时区。 如果输入
   日期具有任何其他有效的时区差值，则 "datetime" 将为一个感知型
   "datetime" 并与 "timezone" "tzinfo" 相对应。

   3.3 版新加入.

email.utils.mktime_tz(tuple)

   将 "parsedate_tz()" 所返回的 10 元组转换为一个 UTC 时间戳（相距
   Epoch 纪元初始的秒数）。 如果元组中的时区项为 "None"，则视为当地时
   间。

email.utils.formatdate(timeval=None, localtime=False, usegmt=False)

   返回 **RFC 2822** 标准的日期字符串，例如:

      Fri, 09 Nov 2001 01:08:47 -0000

   Optional *timeval* if given is a floating point time value as
   accepted by "time.gmtime()" and "time.localtime()", otherwise the
   current time is used.

   Optional *localtime* is a flag that when "True", interprets
   *timeval*, and returns a date relative to the local timezone
   instead of UTC, properly taking daylight savings time into account.
   The default is "False" meaning UTC is used.

   Optional *usegmt* is a flag that when "True", outputs a  date
   string with the timezone as an ascii string "GMT", rather than a
   numeric "-0000". This is needed for some protocols (such as HTTP).
   This only applies when *localtime* is "False".  The default is
   "False".

email.utils.format_datetime(dt, usegmt=False)

   Like "formatdate", but the input is a "datetime" instance.  If it
   is a naive datetime, it is assumed to be "UTC with no information
   about the source timezone", and the conventional "-0000" is used
   for the timezone. If it is an aware "datetime", then the numeric
   timezone offset is used. If it is an aware timezone with offset
   zero, then *usegmt* may be set to "True", in which case the string
   "GMT" is used instead of the numeric timezone offset.  This
   provides a way to generate standards conformant HTTP date headers.

   3.3 版新加入.

email.utils.decode_rfc2231(s)

   Decode the string *s* according to **RFC 2231**.

email.utils.encode_rfc2231(s, charset=None, language=None)

   Encode the string *s* according to **RFC 2231**.  Optional
   *charset* and *language*, if given is the character set name and
   language name to use.  If neither is given, *s* is returned as-is.
   If *charset* is given but *language* is not, the string is encoded
   using the empty string for *language*.

email.utils.collapse_rfc2231_value(value, errors='replace', fallback_charset='us-ascii')

   When a header parameter is encoded in **RFC 2231** format,
   "Message.get_param" may return a 3-tuple containing the character
   set, language, and value.  "collapse_rfc2231_value()" turns this
   into a unicode string.  Optional *errors* is passed to the *errors*
   argument of "str"'s "encode()" method; it defaults to "'replace'".
   Optional *fallback_charset* specifies the character set to use if
   the one in the **RFC 2231** header is not known by Python; it
   defaults to "'us-ascii'".

   For convenience, if the *value* passed to
   "collapse_rfc2231_value()" is not a tuple, it should be a string
   and it is returned unquoted.

email.utils.decode_params(params)

   Decode parameters list according to **RFC 2231**.  *params* is a
   sequence of 2-tuples containing elements of the form "(content-
   type, string-value)".

-[ 备注 ]-

[1] Note that the sign of the timezone offset is the opposite of the
    sign of the "time.timezone" variable for the same timezone; the
    latter variable follows the POSIX standard while this module
    follows **RFC 2822**.
