|
1 | 1 | # frozen_string_literal: true
|
2 | 2 |
|
| 3 | +require "date" |
| 4 | + |
3 | 5 | require_relative "errors"
|
4 | 6 |
|
5 | 7 | module Net
|
6 | 8 | class IMAP < Protocol
|
7 | 9 |
|
| 10 | + # strftime/strptime format for an IMAP4 +date+, excluding optional dquotes. |
| 11 | + # Use via the encode_date and decode_date methods. |
| 12 | + # |
| 13 | + # date = date-text / DQUOTE date-text DQUOTE |
| 14 | + # date-text = date-day "-" date-month "-" date-year |
| 15 | + # |
| 16 | + # date-day = 1*2DIGIT |
| 17 | + # ; Day of month |
| 18 | + # date-month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" / |
| 19 | + # "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec" |
| 20 | + # date-year = 4DIGIT |
| 21 | + STRFDATE = "%d-%b-%Y" |
| 22 | + |
| 23 | + # strftime/strptime format for an IMAP4 +date-time+, including dquotes. |
| 24 | + # See the encode_datetime and decode_datetime methods. |
| 25 | + # |
| 26 | + # date-time = DQUOTE date-day-fixed "-" date-month "-" date-year |
| 27 | + # SP time SP zone DQUOTE |
| 28 | + # |
| 29 | + # date-day-fixed = (SP DIGIT) / 2DIGIT |
| 30 | + # ; Fixed-format version of date-day |
| 31 | + # date-month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" / |
| 32 | + # "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec" |
| 33 | + # date-year = 4DIGIT |
| 34 | + # time = 2DIGIT ":" 2DIGIT ":" 2DIGIT |
| 35 | + # ; Hours minutes seconds |
| 36 | + # zone = ("+" / "-") 4DIGIT |
| 37 | + # ; Signed four-digit value of hhmm representing |
| 38 | + # ; hours and minutes east of Greenwich (that is, |
| 39 | + # ; the amount that the given time differs from |
| 40 | + # ; Universal Time). Subtracting the timezone |
| 41 | + # ; from the given time will give the UT form. |
| 42 | + # ; The Universal Time zone is "+0000". |
| 43 | + # |
| 44 | + # Note that Time.strptime <tt>"%d"</tt> flexibly parses either space or zero |
| 45 | + # padding. However, the DQUOTEs are *not* optional. |
| 46 | + STRFTIME = '"%d-%b-%Y %H:%M:%S %z"' |
| 47 | + |
8 | 48 | # Decode a string from modified UTF-7 format to UTF-8.
|
9 | 49 | #
|
10 | 50 | # UTF-7 is a 7-bit encoding of Unicode [UTF7]. IMAP uses a
|
@@ -35,14 +75,70 @@ def self.encode_utf7(s)
|
35 | 75 | }.force_encoding("ASCII-8BIT")
|
36 | 76 | end
|
37 | 77 |
|
38 |
| - # Formats +time+ as an IMAP-style date. |
39 |
| - def self.format_date(time) |
40 |
| - return time.strftime('%d-%b-%Y') |
| 78 | + # Formats +time+ as an IMAP4 date. |
| 79 | + def self.encode_date(date) |
| 80 | + date.to_date.strftime STRFDATE |
| 81 | + end |
| 82 | + |
| 83 | + # :call-seq: decode_date(string) -> Date |
| 84 | + # |
| 85 | + # Decodes +string+ as an IMAP formatted "date". |
| 86 | + # |
| 87 | + # Double quotes are optional. Day of month may be padded with zero or |
| 88 | + # space. See STRFDATE. |
| 89 | + def self.decode_date(string) |
| 90 | + string = string.delete_prefix('"').delete_suffix('"') |
| 91 | + Date.strptime(string, STRFDATE) |
| 92 | + end |
| 93 | + |
| 94 | + # :call-seq: encode_datetime(time) -> string |
| 95 | + # |
| 96 | + # Formats +time+ as an IMAP4 date-time. |
| 97 | + def self.encode_datetime(time) |
| 98 | + time.to_datetime.strftime STRFTIME |
41 | 99 | end
|
42 | 100 |
|
43 |
| - # Formats +time+ as an IMAP-style date-time. |
| 101 | + # :call-seq: decode_datetime(string) -> DateTime |
| 102 | + # |
| 103 | + # Decodes +string+ as an IMAP4 formatted "date-time". |
| 104 | + # |
| 105 | + # Note that double quotes are not optional. See STRFTIME. |
| 106 | + def self.decode_datetime(string) |
| 107 | + DateTime.strptime(string, STRFTIME) |
| 108 | + end |
| 109 | + |
| 110 | + # :call-seq: decode_time(string) -> Time |
| 111 | + # |
| 112 | + # Decodes +string+ as an IMAP4 formatted "date-time". |
| 113 | + # |
| 114 | + # Same as +decode_datetime+, but returning a Time instead. |
| 115 | + def self.decode_time(string) |
| 116 | + decode_datetime(string).to_time |
| 117 | + end |
| 118 | + |
| 119 | + class << self |
| 120 | + alias encode_time encode_datetime |
| 121 | + alias format_date encode_date |
| 122 | + alias format_time encode_time |
| 123 | + alias parse_date decode_date |
| 124 | + alias parse_datetime decode_datetime |
| 125 | + alias parse_time decode_time |
| 126 | + |
| 127 | + # alias format_datetime encode_datetime # n.b. this is overridden below... |
| 128 | + end |
| 129 | + |
| 130 | + # DEPRECATED:: The original version returned incorrectly formatted strings. |
| 131 | + # Strings returned by encode_datetime or format_time use the |
| 132 | + # correct IMAP4rev1 syntax for "date-time". |
| 133 | + # |
| 134 | + # This invalid format has been temporarily retained for backward |
| 135 | + # compatibility. A future release will change this method to return the |
| 136 | + # correct format. |
44 | 137 | def self.format_datetime(time)
|
45 |
| - return time.strftime('%d-%b-%Y %H:%M %z') |
| 138 | + warn("#{self}.format_datetime incorrectly formats IMAP date-time. " \ |
| 139 | + "Convert to #{self}.encode_datetime or #{self}.format_time instead.", |
| 140 | + uplevel: 1, category: :deprecated) |
| 141 | + time.strftime("%d-%b-%Y %H:%M %z") |
46 | 142 | end
|
47 | 143 |
|
48 | 144 | # Common validators of number and nz_number types
|
|
0 commit comments