Mercurial > hg
annotate mercurial/utils/dateutil.py @ 51099:eba138890c64
revlog: move entry writing in the inner object
This is the second big piece of API we want to live on the inner object. With
this the inner object have freedom it needs to implement things internally.
(except for the delayed write feature of the changelog, that will be migrated in coming changesets)
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Thu, 19 Oct 2023 05:19:55 +0200 |
parents | faccec1edc2c |
children | 9d3721552b6c |
rev | line source |
---|---|
36607
c6061cadb400
util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents:
36588
diff
changeset
|
1 # util.py - Mercurial utility functions relative to dates |
8226
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
2 # |
36607
c6061cadb400
util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents:
36588
diff
changeset
|
3 # Copyright 2018 Boris Feld <boris.feld@octobus.net> |
8226
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
4 # |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
10263 | 6 # GNU General Public License version 2 or any later version. |
1082 | 7 |
27358
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
8 |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
9 import calendar |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
10 import datetime |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
11 import time |
3769 | 12 |
36607
c6061cadb400
util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents:
36588
diff
changeset
|
13 from ..i18n import _ |
c6061cadb400
util: extract all date-related utils in utils/dateutil module
Boris Feld <boris.feld@octobus.net>
parents:
36588
diff
changeset
|
14 from .. import ( |
27358
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
15 encoding, |
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
16 error, |
28818
6041fb8f2da8
pycompat: add empty and queue to handle py3 divergence
timeless <timeless@mozdev.org>
parents:
28497
diff
changeset
|
17 pycompat, |
27358
ac839ee45b6a
util: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27357
diff
changeset
|
18 ) |
3769 | 19 |
46641
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
20 if pycompat.TYPE_CHECKING: |
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
21 from typing import ( |
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
22 Callable, |
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
23 Dict, |
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
24 Iterable, |
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
25 Optional, |
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
26 Tuple, |
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
27 Union, |
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
28 ) |
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
29 |
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
30 hgdate = Tuple[float, int] # (unixtime, offset) |
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
31 |
2609
6c5b1b5cc160
util.parsedate should understand dates from hg export
Chris Mason <mason@suse.com>
parents:
2601
diff
changeset
|
32 # used by parsedate |
3808
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
33 defaultdateformats = ( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
34 b'%Y-%m-%dT%H:%M:%S', # the 'real' ISO8601 |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
35 b'%Y-%m-%dT%H:%M', # without seconds |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
36 b'%Y-%m-%dT%H%M%S', # another awful but legal variant without : |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
37 b'%Y-%m-%dT%H%M', # without seconds |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
38 b'%Y-%m-%d %H:%M:%S', # our common legal variant |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
39 b'%Y-%m-%d %H:%M', # without seconds |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
40 b'%Y-%m-%d %H%M%S', # without : |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
41 b'%Y-%m-%d %H%M', # without seconds |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
42 b'%Y-%m-%d %I:%M:%S%p', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
43 b'%Y-%m-%d %H:%M', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
44 b'%Y-%m-%d %I:%M%p', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
45 b'%Y-%m-%d', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
46 b'%m-%d', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
47 b'%m/%d', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
48 b'%m/%d/%y', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
49 b'%m/%d/%Y', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
50 b'%a %b %d %H:%M:%S %Y', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
51 b'%a %b %d %I:%M:%S%p %Y', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
52 b'%a, %d %b %Y %H:%M:%S', # GNU coreutils "/bin/date --rfc-2822" |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
53 b'%b %d %H:%M:%S %Y', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
54 b'%b %d %I:%M:%S%p %Y', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
55 b'%b %d %H:%M:%S', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
56 b'%b %d %I:%M:%S%p', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
57 b'%b %d %H:%M', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
58 b'%b %d %I:%M%p', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
59 b'%b %d %Y', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
60 b'%b %d', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
61 b'%H:%M:%S', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
62 b'%I:%M:%S%p', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
63 b'%H:%M', |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
64 b'%I:%M%p', |
3808
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
65 ) |
2609
6c5b1b5cc160
util.parsedate should understand dates from hg export
Chris Mason <mason@suse.com>
parents:
2601
diff
changeset
|
66 |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
43781
diff
changeset
|
67 extendeddateformats = defaultdateformats + ( |
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
43781
diff
changeset
|
68 b"%Y", |
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
43781
diff
changeset
|
69 b"%Y-%m", |
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
43781
diff
changeset
|
70 b"%b", |
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
43781
diff
changeset
|
71 b"%b %Y", |
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
43781
diff
changeset
|
72 ) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
73 |
36362
01e29e885600
util: add a file object proxy that can read at most N bytes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36266
diff
changeset
|
74 |
19287
8b04e1344111
util: add an optional timestamp parameter to makedate
Bryan O'Sullivan <bryano@fb.com>
parents:
19286
diff
changeset
|
75 def makedate(timestamp=None): |
46641
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
76 # type: (Optional[float]) -> hgdate |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
43781
diff
changeset
|
77 """Return a unix timestamp (or the current time) as a (unixtime, |
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
43781
diff
changeset
|
78 offset) tuple based off the local timezone.""" |
19287
8b04e1344111
util: add an optional timestamp parameter to makedate
Bryan O'Sullivan <bryano@fb.com>
parents:
19286
diff
changeset
|
79 if timestamp is None: |
8b04e1344111
util: add an optional timestamp parameter to makedate
Bryan O'Sullivan <bryano@fb.com>
parents:
19286
diff
changeset
|
80 timestamp = time.time() |
19286
78501209488a
util: rename ct variable in makedate to timestamp
Bryan O'Sullivan <bryano@fb.com>
parents:
19211
diff
changeset
|
81 if timestamp < 0: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
82 hint = _(b"check your clock") |
46419
6894c9ef4dcd
errors: use InputError for incorrectly formatted dates
Martin von Zweigbergk <martinvonz@google.com>
parents:
45942
diff
changeset
|
83 raise error.InputError( |
6894c9ef4dcd
errors: use InputError for incorrectly formatted dates
Martin von Zweigbergk <martinvonz@google.com>
parents:
45942
diff
changeset
|
84 _(b"negative timestamp: %d") % timestamp, hint=hint |
6894c9ef4dcd
errors: use InputError for incorrectly formatted dates
Martin von Zweigbergk <martinvonz@google.com>
parents:
45942
diff
changeset
|
85 ) |
50752
faccec1edc2c
utils: stop using datetime.utcfromtimestamp() deprecated in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents:
48875
diff
changeset
|
86 tz = round( |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
87 timestamp |
50752
faccec1edc2c
utils: stop using datetime.utcfromtimestamp() deprecated in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents:
48875
diff
changeset
|
88 - datetime.datetime.fromtimestamp( |
faccec1edc2c
utils: stop using datetime.utcfromtimestamp() deprecated in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents:
48875
diff
changeset
|
89 timestamp, |
faccec1edc2c
utils: stop using datetime.utcfromtimestamp() deprecated in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents:
48875
diff
changeset
|
90 ) |
faccec1edc2c
utils: stop using datetime.utcfromtimestamp() deprecated in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents:
48875
diff
changeset
|
91 .replace(tzinfo=datetime.timezone.utc) |
faccec1edc2c
utils: stop using datetime.utcfromtimestamp() deprecated in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents:
48875
diff
changeset
|
92 .timestamp() |
faccec1edc2c
utils: stop using datetime.utcfromtimestamp() deprecated in Python 3.12
Mads Kiilerich <mads@kiilerich.com>
parents:
48875
diff
changeset
|
93 ) |
19286
78501209488a
util: rename ct variable in makedate to timestamp
Bryan O'Sullivan <bryano@fb.com>
parents:
19211
diff
changeset
|
94 return timestamp, tz |
1329
8f06817bf266
Allow files to be opened in text mode, even on Windows.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1321
diff
changeset
|
95 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
96 |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
97 def datestr(date=None, format=b'%a %b %d %H:%M:%S %Y %1%2'): |
46641
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
98 # type: (Optional[hgdate], bytes) -> bytes |
1321
b47f96a178a3
Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1320
diff
changeset
|
99 """represent a (unixtime, offset) tuple as a localized time. |
b47f96a178a3
Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1320
diff
changeset
|
100 unixtime is seconds since the epoch, and offset is the time zone's |
28865
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
101 number of seconds away from UTC. |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
102 |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
103 >>> datestr((0, 0)) |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
104 'Thu Jan 01 00:00:00 1970 +0000' |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
105 >>> datestr((42, 0)) |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
106 'Thu Jan 01 00:00:42 1970 +0000' |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
107 >>> datestr((-42, 0)) |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
108 'Wed Dec 31 23:59:18 1969 +0000' |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
109 >>> datestr((0x7fffffff, 0)) |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
110 'Tue Jan 19 03:14:07 2038 +0000' |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
111 >>> datestr((-0x80000000, 0)) |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
112 'Fri Dec 13 20:45:52 1901 +0000' |
16255662446d
util: add doctest to datestr()
Adrian Buehlmann <adrian@cadifra.com>
parents:
28864
diff
changeset
|
113 """ |
1321
b47f96a178a3
Clean up date and timezone handling.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1320
diff
changeset
|
114 t, tz = date or makedate() |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
115 if b"%1" in format or b"%2" in format or b"%z" in format: |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
116 sign = (tz > 0) and b"-" or b"+" |
9029
0001e49f1c11
compat: use // for integer division
Alejandro Santos <alejolp@alejolp.com>
parents:
8938
diff
changeset
|
117 minutes = abs(tz) // 60 |
27066
6f1f8e88f036
util.datestr: use divmod()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27016
diff
changeset
|
118 q, r = divmod(minutes, 60) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
119 format = format.replace(b"%z", b"%1%2") |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
120 format = format.replace(b"%1", b"%c%02d" % (sign, q)) |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
121 format = format.replace(b"%2", b"%02d" % r) |
28825
87c6ad2251d8
date: reallow negative timestamp, fix for Windows buggy gmtime() (issue2513)
Florent Gallaire <fgallaire@gmail.com>
parents:
28818
diff
changeset
|
122 d = t - tz |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
123 if d > 0x7FFFFFFF: |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
124 d = 0x7FFFFFFF |
28864
b0811a9fe67c
date: fix boundary check of negative integer
Florent Gallaire <fgallaire@gmail.com>
parents:
28835
diff
changeset
|
125 elif d < -0x80000000: |
b0811a9fe67c
date: fix boundary check of negative integer
Florent Gallaire <fgallaire@gmail.com>
parents:
28835
diff
changeset
|
126 d = -0x80000000 |
28825
87c6ad2251d8
date: reallow negative timestamp, fix for Windows buggy gmtime() (issue2513)
Florent Gallaire <fgallaire@gmail.com>
parents:
28818
diff
changeset
|
127 # Never use time.gmtime() and datetime.datetime.fromtimestamp() |
87c6ad2251d8
date: reallow negative timestamp, fix for Windows buggy gmtime() (issue2513)
Florent Gallaire <fgallaire@gmail.com>
parents:
28818
diff
changeset
|
128 # because they use the gmtime() system call which is buggy on Windows |
87c6ad2251d8
date: reallow negative timestamp, fix for Windows buggy gmtime() (issue2513)
Florent Gallaire <fgallaire@gmail.com>
parents:
28818
diff
changeset
|
129 # for negative values. |
87c6ad2251d8
date: reallow negative timestamp, fix for Windows buggy gmtime() (issue2513)
Florent Gallaire <fgallaire@gmail.com>
parents:
28818
diff
changeset
|
130 t = datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=d) |
31449
756175623f2e
py3: call strftime() with native str type
Yuya Nishihara <yuya@tcha.org>
parents:
31448
diff
changeset
|
131 s = encoding.strtolocal(t.strftime(encoding.strfromlocal(format))) |
1987
04c17fc39c84
add changelog style to command line template.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1976
diff
changeset
|
132 return s |
1829
b0f6af327fd4
hgwebdir: export collections of repos
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1635
diff
changeset
|
133 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
134 |
6134
7b937b26adf7
Make annotae/grep print short dates with -q/--quiet.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6111
diff
changeset
|
135 def shortdate(date=None): |
46641
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
136 # type: (Optional[hgdate]) -> bytes |
6134
7b937b26adf7
Make annotae/grep print short dates with -q/--quiet.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6111
diff
changeset
|
137 """turn (timestamp, tzoff) tuple into iso 8631 date.""" |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
138 return datestr(date, format=b'%Y-%m-%d') |
6134
7b937b26adf7
Make annotae/grep print short dates with -q/--quiet.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6111
diff
changeset
|
139 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
140 |
29636
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
141 def parsetimezone(s): |
46641
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
142 # type: (bytes) -> Tuple[Optional[int], bytes] |
29636
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
143 """find a trailing timezone, if any, in string, and return a |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
43781
diff
changeset
|
144 (offset, remainder) pair""" |
36551
98d4c642d7f2
py3: fix string slicing in util.parsetimezone()
Yuya Nishihara <yuya@tcha.org>
parents:
36539
diff
changeset
|
145 s = pycompat.bytestr(s) |
29636
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
146 |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
147 if s.endswith(b"GMT") or s.endswith(b"UTC"): |
29636
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
148 return 0, s[:-3].rstrip() |
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
149 |
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
150 # Unix-style timezones [+-]hhmm |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
151 if len(s) >= 5 and s[-5] in b"+-" and s[-4:].isdigit(): |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
152 sign = (s[-5] == b"+") and 1 or -1 |
29636
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
153 hours = int(s[-4:-2]) |
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
154 minutes = int(s[-2:]) |
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
155 return -sign * (hours * 60 + minutes) * 60, s[:-5].rstrip() |
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
156 |
29637
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
157 # ISO8601 trailing Z |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
158 if s.endswith(b"Z") and s[-2:-1].isdigit(): |
29637
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
159 return 0, s[:-1] |
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
160 |
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
161 # ISO8601-style [+-]hh:mm |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
162 if ( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
163 len(s) >= 6 |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
164 and s[-6] in b"+-" |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
165 and s[-3] == b":" |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
166 and s[-5:-3].isdigit() |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
167 and s[-2:].isdigit() |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
168 ): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
169 sign = (s[-6] == b"+") and 1 or -1 |
29637
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
170 hours = int(s[-5:-3]) |
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
171 minutes = int(s[-2:]) |
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
172 return -sign * (hours * 60 + minutes) * 60, s[:-6] |
46b2ccce7fde
date: parse ISO-style Z and +hh:mm timezone specs
Matt Mackall <mpm@selenic.com>
parents:
29636
diff
changeset
|
173 |
29636
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
174 return None, s |
26126
7b625baed995
util: extract function that parses timezone string
Yuya Nishihara <yuya@tcha.org>
parents:
26098
diff
changeset
|
175 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
176 |
31393
8b6927eb7efd
util: don't use mutable default argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31368
diff
changeset
|
177 def strdate(string, format, defaults=None): |
46641
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
178 # type: (bytes, bytes, Optional[Dict[bytes, Tuple[bytes, bytes]]]) -> hgdate |
2522
85f796baab10
Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents:
2480
diff
changeset
|
179 """parse a localized time string and return a (unixtime, offset) tuple. |
85f796baab10
Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents:
2480
diff
changeset
|
180 if the string cannot be parsed, ValueError is raised.""" |
31465
da83f12d7a88
util: explicitly tests for None
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31453
diff
changeset
|
181 if defaults is None: |
da83f12d7a88
util: explicitly tests for None
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31453
diff
changeset
|
182 defaults = {} |
31393
8b6927eb7efd
util: don't use mutable default argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents:
31368
diff
changeset
|
183 |
3255
e96d2956eb4a
util.strdate: compute timestamp using UTC, not local timezone
Jose M. Prieto <jmprieto@gmx.net>
parents:
3176
diff
changeset
|
184 # NOTE: unixtime = localunixtime + offset |
29636
84ef4517de03
date: refactor timezone parsing
Matt Mackall <mpm@selenic.com>
parents:
29613
diff
changeset
|
185 offset, date = parsetimezone(string) |
3808
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
186 |
3812 | 187 # add missing elements from defaults |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
188 usenow = False # default to using biased defaults |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
189 for part in ( |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
190 b"S", |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
191 b"M", |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
192 b"HI", |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
193 b"d", |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
194 b"mb", |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
195 b"yY", |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
196 ): # decreasing specificity |
32154
52e222eef646
py3: use pycompat.bytestr instead of bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents:
32153
diff
changeset
|
197 part = pycompat.bytestr(part) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
198 found = [True for p in part if (b"%" + p) in format] |
3812 | 199 if not found: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
200 date += b"@" + defaults[part][usenow] |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
201 format += b"@%" + part[0] |
13212
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
202 else: |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
203 # We've found a specific time element, less specific time |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
204 # elements are relative to today |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
205 usenow = True |
3808
d6529582942a
improve date parsing for numerous new date formats
Matt Mackall <mpm@selenic.com>
parents:
3807
diff
changeset
|
206 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
207 timetuple = time.strptime( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
208 encoding.strfromlocal(date), encoding.strfromlocal(format) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
209 ) |
3256
e5c9a084ffe3
util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents:
3255
diff
changeset
|
210 localunixtime = int(calendar.timegm(timetuple)) |
e5c9a084ffe3
util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents:
3255
diff
changeset
|
211 if offset is None: |
e5c9a084ffe3
util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents:
3255
diff
changeset
|
212 # local timezone |
e5c9a084ffe3
util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents:
3255
diff
changeset
|
213 unixtime = int(time.mktime(timetuple)) |
e5c9a084ffe3
util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents:
3255
diff
changeset
|
214 offset = unixtime - localunixtime |
e5c9a084ffe3
util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents:
3255
diff
changeset
|
215 else: |
e5c9a084ffe3
util.strdate: assume local time when no timezone specified
Jose M. Prieto <jmprieto@gmx.net>
parents:
3255
diff
changeset
|
216 unixtime = localunixtime + offset |
3255
e96d2956eb4a
util.strdate: compute timestamp using UTC, not local timezone
Jose M. Prieto <jmprieto@gmx.net>
parents:
3176
diff
changeset
|
217 return unixtime, offset |
2522
85f796baab10
Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents:
2480
diff
changeset
|
218 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
219 |
26311
60dd8e3977f0
util: avoid mutable default arguments
Siddharth Agarwal <sid0@fb.com>
parents:
26267
diff
changeset
|
220 def parsedate(date, formats=None, bias=None): |
46641
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
221 # type: (Union[bytes, hgdate], Optional[Iterable[bytes]], Optional[Dict[bytes, bytes]]) -> hgdate |
13212
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
222 """parse a localized date/time and return a (unixtime, offset) tuple. |
6139
989467e8e3a9
Fix bad behaviour when specifying an invalid date (issue700)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6135
diff
changeset
|
223 |
2522
85f796baab10
Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents:
2480
diff
changeset
|
224 The date may be a "unixtime offset" string or in one of the specified |
6139
989467e8e3a9
Fix bad behaviour when specifying an invalid date (issue700)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6135
diff
changeset
|
225 formats. If the date already is a (unixtime, offset) tuple, it is returned. |
18537
ae60735e37d2
dates: support 'today' and 'yesterday' in parsedate (issue3764)
Paul Cavallaro <ptc@fb.com>
parents:
18326
diff
changeset
|
226 |
34362
b76937fafe8a
py3: work around bytes/unicode divergence in parsedate()
Yuya Nishihara <yuya@tcha.org>
parents:
34361
diff
changeset
|
227 >>> parsedate(b' today ') == parsedate( |
b76937fafe8a
py3: work around bytes/unicode divergence in parsedate()
Yuya Nishihara <yuya@tcha.org>
parents:
34361
diff
changeset
|
228 ... datetime.date.today().strftime('%b %d').encode('ascii')) |
18537
ae60735e37d2
dates: support 'today' and 'yesterday' in parsedate (issue3764)
Paul Cavallaro <ptc@fb.com>
parents:
18326
diff
changeset
|
229 True |
34362
b76937fafe8a
py3: work around bytes/unicode divergence in parsedate()
Yuya Nishihara <yuya@tcha.org>
parents:
34361
diff
changeset
|
230 >>> parsedate(b'yesterday ') == parsedate( |
b76937fafe8a
py3: work around bytes/unicode divergence in parsedate()
Yuya Nishihara <yuya@tcha.org>
parents:
34361
diff
changeset
|
231 ... (datetime.date.today() - datetime.timedelta(days=1) |
b76937fafe8a
py3: work around bytes/unicode divergence in parsedate()
Yuya Nishihara <yuya@tcha.org>
parents:
34361
diff
changeset
|
232 ... ).strftime('%b %d').encode('ascii')) |
18537
ae60735e37d2
dates: support 'today' and 'yesterday' in parsedate (issue3764)
Paul Cavallaro <ptc@fb.com>
parents:
18326
diff
changeset
|
233 True |
18614
b2586e2cc67a
parsedate: understand "now" as a shortcut for the current time
Augie Fackler <raf@durin42.com>
parents:
18603
diff
changeset
|
234 >>> now, tz = makedate() |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34084
diff
changeset
|
235 >>> strnow, strtz = parsedate(b'now') |
18614
b2586e2cc67a
parsedate: understand "now" as a shortcut for the current time
Augie Fackler <raf@durin42.com>
parents:
18603
diff
changeset
|
236 >>> (strnow - now) < 1 |
b2586e2cc67a
parsedate: understand "now" as a shortcut for the current time
Augie Fackler <raf@durin42.com>
parents:
18603
diff
changeset
|
237 True |
b2586e2cc67a
parsedate: understand "now" as a shortcut for the current time
Augie Fackler <raf@durin42.com>
parents:
18603
diff
changeset
|
238 >>> tz == strtz |
b2586e2cc67a
parsedate: understand "now" as a shortcut for the current time
Augie Fackler <raf@durin42.com>
parents:
18603
diff
changeset
|
239 True |
43781
b65bd4b61d78
dateutil: correct default for Ymd in parsedate
Jun Wu <quark@fb.com>
parents:
43506
diff
changeset
|
240 >>> parsedate(b'2000 UTC', formats=extendeddateformats) |
b65bd4b61d78
dateutil: correct default for Ymd in parsedate
Jun Wu <quark@fb.com>
parents:
43506
diff
changeset
|
241 (946684800, 0) |
6139
989467e8e3a9
Fix bad behaviour when specifying an invalid date (issue700)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6135
diff
changeset
|
242 """ |
26311
60dd8e3977f0
util: avoid mutable default arguments
Siddharth Agarwal <sid0@fb.com>
parents:
26267
diff
changeset
|
243 if bias is None: |
60dd8e3977f0
util: avoid mutable default arguments
Siddharth Agarwal <sid0@fb.com>
parents:
26267
diff
changeset
|
244 bias = {} |
6139
989467e8e3a9
Fix bad behaviour when specifying an invalid date (issue700)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6135
diff
changeset
|
245 if not date: |
3807
e43b48f0f718
parsedate: allow '' for epoch
Matt Mackall <mpm@selenic.com>
parents:
3806
diff
changeset
|
246 return 0, 0 |
46641
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
247 if isinstance(date, tuple): |
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
248 if len(date) == 2: |
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
249 return date |
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
250 else: |
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
251 raise error.ProgrammingError(b"invalid date format") |
2609
6c5b1b5cc160
util.parsedate should understand dates from hg export
Chris Mason <mason@suse.com>
parents:
2601
diff
changeset
|
252 if not formats: |
6c5b1b5cc160
util.parsedate should understand dates from hg export
Chris Mason <mason@suse.com>
parents:
2601
diff
changeset
|
253 formats = defaultdateformats |
6139
989467e8e3a9
Fix bad behaviour when specifying an invalid date (issue700)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6135
diff
changeset
|
254 date = date.strip() |
18537
ae60735e37d2
dates: support 'today' and 'yesterday' in parsedate (issue3764)
Paul Cavallaro <ptc@fb.com>
parents:
18326
diff
changeset
|
255 |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
256 if date == b'now' or date == _(b'now'): |
18614
b2586e2cc67a
parsedate: understand "now" as a shortcut for the current time
Augie Fackler <raf@durin42.com>
parents:
18603
diff
changeset
|
257 return makedate() |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
258 if date == b'today' or date == _(b'today'): |
43506
9f70512ae2cf
cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents:
43077
diff
changeset
|
259 date = datetime.date.today().strftime('%b %d') |
34362
b76937fafe8a
py3: work around bytes/unicode divergence in parsedate()
Yuya Nishihara <yuya@tcha.org>
parents:
34361
diff
changeset
|
260 date = encoding.strtolocal(date) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
261 elif date == b'yesterday' or date == _(b'yesterday'): |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
262 date = (datetime.date.today() - datetime.timedelta(days=1)).strftime( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
263 r'%b %d' |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
264 ) |
34362
b76937fafe8a
py3: work around bytes/unicode divergence in parsedate()
Yuya Nishihara <yuya@tcha.org>
parents:
34361
diff
changeset
|
265 date = encoding.strtolocal(date) |
18537
ae60735e37d2
dates: support 'today' and 'yesterday' in parsedate (issue3764)
Paul Cavallaro <ptc@fb.com>
parents:
18326
diff
changeset
|
266 |
2522
85f796baab10
Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents:
2480
diff
changeset
|
267 try: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
268 when, offset = map(int, date.split(b' ')) |
2523
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
269 except ValueError: |
3812 | 270 # fill out defaults |
271 now = makedate() | |
13212
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
272 defaults = {} |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
273 for part in (b"d", b"mb", b"yY", b"HI", b"M", b"S"): |
13212
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
274 # this piece is for rounding the specific end of unknowns |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
275 b = bias.get(part) |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
276 if b is None: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
277 if part[0:1] in b"HMS": |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
278 b = b"00" |
3812 | 279 else: |
43781
b65bd4b61d78
dateutil: correct default for Ymd in parsedate
Jun Wu <quark@fb.com>
parents:
43506
diff
changeset
|
280 # year, month, and day start from 1 |
b65bd4b61d78
dateutil: correct default for Ymd in parsedate
Jun Wu <quark@fb.com>
parents:
43506
diff
changeset
|
281 b = b"1" |
13212
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
282 |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
283 # this piece is for matching the generic end to today's date |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
284 n = datestr(now, b"%" + part[0:1]) |
13212
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
285 |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
286 defaults[part] = (b, n) |
3812 | 287 |
2523
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
288 for format in formats: |
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
289 try: |
6139
989467e8e3a9
Fix bad behaviour when specifying an invalid date (issue700)
Thomas Arendsen Hein <thomas@intevation.de>
parents:
6135
diff
changeset
|
290 when, offset = strdate(date, format, defaults) |
6087
12856a1742dc
better handle errors with date parsing (issue983)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
5917
diff
changeset
|
291 except (ValueError, OverflowError): |
2523
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
292 pass |
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
293 else: |
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
294 break |
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
295 else: |
36539
0c2eeaca0577
util: use pycompat.bytestr() on repr() in date parse abort
Augie Fackler <augie@google.com>
parents:
36525
diff
changeset
|
296 raise error.ParseError( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
297 _(b'invalid date: %r') % pycompat.bytestr(date) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
298 ) |
2523
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
299 # validate explicit (probably user-specified) date and |
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
300 # time zone offset. values must fit in signed 32 bits for |
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
301 # current 32-bit linux runtimes. timezones go from UTC-12 |
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
302 # to UTC+14 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
303 if when < -0x80000000 or when > 0x7FFFFFFF: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
304 raise error.ParseError(_(b'date exceeds 32 bits: %d') % when) |
2523
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
305 if offset < -50400 or offset > 43200: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
306 raise error.ParseError(_(b'impossible time zone offset: %d') % offset) |
2523
4ab59a3acd16
validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
2522
diff
changeset
|
307 return when, offset |
2522
85f796baab10
Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents:
2480
diff
changeset
|
308 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
309 |
3812 | 310 def matchdate(date): |
46641
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
311 # type: (bytes) -> Callable[[float], bool] |
3812 | 312 """Return a function that matches a given date match specifier |
313 | |
314 Formats include: | |
315 | |
316 '{date}' match a given date to the accuracy provided | |
317 | |
318 '<{date}' on or before a given date | |
319 | |
320 '>{date}' on or after a given date | |
321 | |
34131
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34084
diff
changeset
|
322 >>> p1 = parsedate(b"10:29:59") |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34084
diff
changeset
|
323 >>> p2 = parsedate(b"10:30:00") |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34084
diff
changeset
|
324 >>> p3 = parsedate(b"10:30:59") |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34084
diff
changeset
|
325 >>> p4 = parsedate(b"10:31:00") |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34084
diff
changeset
|
326 >>> p5 = parsedate(b"Sep 15 10:30:00 1999") |
0fa781320203
doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents:
34084
diff
changeset
|
327 >>> f = matchdate(b"10:30") |
13212
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
328 >>> f(p1[0]) |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
329 False |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
330 >>> f(p2[0]) |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
331 True |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
332 >>> f(p3[0]) |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
333 True |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
334 >>> f(p4[0]) |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
335 False |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
336 >>> f(p5[0]) |
5d0a30fad7de
date: fix matching of underspecified date ranges
Matt Mackall <mpm@selenic.com>
parents:
13204
diff
changeset
|
337 False |
3812 | 338 """ |
339 | |
340 def lower(date): | |
46641
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
341 # type: (bytes) -> float |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
342 d = {b'mb': b"1", b'd': b"1"} |
6230
c7253d1a774e
dates: Fix bare times to be relative to "today"
Matt Mackall <mpm@selenic.com>
parents:
6229
diff
changeset
|
343 return parsedate(date, extendeddateformats, d)[0] |
3812 | 344 |
345 def upper(date): | |
46641
15c2f9220ae8
typing: add type annotations to mercurial/utils/dateutil.py
Matt Harbison <matt_harbison@yahoo.com>
parents:
46419
diff
changeset
|
346 # type: (bytes) -> float |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
347 d = {b'mb': b"12", b'HI': b"23", b'M': b"59", b'S': b"59"} |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
348 for days in (b"31", b"30", b"29"): |
3812 | 349 try: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
350 d[b"d"] = days |
3812 | 351 return parsedate(date, extendeddateformats, d)[0] |
36234 | 352 except error.ParseError: |
3812 | 353 pass |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
354 d[b"d"] = b"28" |
3812 | 355 return parsedate(date, extendeddateformats, d)[0] |
356 | |
7953
8c6f823efcc9
Correct a bug on date formats with '>' or '<' accompanied by space characters.
Justin Peng <justin.peng.sw@gmail.com>
parents:
7948
diff
changeset
|
357 date = date.strip() |
13780
bc7b5d1c1999
util: dates cannot consist entirely of whitespace (issue2732)
Idan Kamara <idankk86@gmail.com>
parents:
13734
diff
changeset
|
358 |
bc7b5d1c1999
util: dates cannot consist entirely of whitespace (issue2732)
Idan Kamara <idankk86@gmail.com>
parents:
13734
diff
changeset
|
359 if not date: |
46419
6894c9ef4dcd
errors: use InputError for incorrectly formatted dates
Martin von Zweigbergk <martinvonz@google.com>
parents:
45942
diff
changeset
|
360 raise error.InputError( |
6894c9ef4dcd
errors: use InputError for incorrectly formatted dates
Martin von Zweigbergk <martinvonz@google.com>
parents:
45942
diff
changeset
|
361 _(b"dates cannot consist entirely of whitespace") |
6894c9ef4dcd
errors: use InputError for incorrectly formatted dates
Martin von Zweigbergk <martinvonz@google.com>
parents:
45942
diff
changeset
|
362 ) |
40256 | 363 elif date[0:1] == b"<": |
13869
b470894c33f8
date: fixup breakage from ">" fix
Matt Mackall <mpm@selenic.com>
parents:
13867
diff
changeset
|
364 if not date[1:]: |
46419
6894c9ef4dcd
errors: use InputError for incorrectly formatted dates
Martin von Zweigbergk <martinvonz@google.com>
parents:
45942
diff
changeset
|
365 raise error.InputError(_(b"invalid day spec, use '<DATE'")) |
3812 | 366 when = upper(date[1:]) |
367 return lambda x: x <= when | |
40256 | 368 elif date[0:1] == b">": |
13869
b470894c33f8
date: fixup breakage from ">" fix
Matt Mackall <mpm@selenic.com>
parents:
13867
diff
changeset
|
369 if not date[1:]: |
46419
6894c9ef4dcd
errors: use InputError for incorrectly formatted dates
Martin von Zweigbergk <martinvonz@google.com>
parents:
45942
diff
changeset
|
370 raise error.InputError(_(b"invalid day spec, use '>DATE'")) |
3812 | 371 when = lower(date[1:]) |
372 return lambda x: x >= when | |
40256 | 373 elif date[0:1] == b"-": |
3812 | 374 try: |
375 days = int(date[1:]) | |
376 except ValueError: | |
46419
6894c9ef4dcd
errors: use InputError for incorrectly formatted dates
Martin von Zweigbergk <martinvonz@google.com>
parents:
45942
diff
changeset
|
377 raise error.InputError(_(b"invalid day spec: %s") % date[1:]) |
13889
9a96efc4af8a
util: make 'hg log -d --2' abort (issue2734)
Yun Lee <yunlee.bj@gmail.com>
parents:
13886
diff
changeset
|
378 if days < 0: |
46419
6894c9ef4dcd
errors: use InputError for incorrectly formatted dates
Martin von Zweigbergk <martinvonz@google.com>
parents:
45942
diff
changeset
|
379 raise error.InputError( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
380 _(b"%s must be nonnegative (see 'hg help dates')") % date[1:] |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
40256
diff
changeset
|
381 ) |
3812 | 382 when = makedate()[0] - days * 3600 * 24 |
3813 | 383 return lambda x: x >= when |
40256 | 384 elif b" to " in date: |
385 a, b = date.split(b" to ") | |
3812 | 386 start, stop = lower(a), upper(b) |
387 return lambda x: x >= start and x <= stop | |
388 else: | |
389 start, stop = lower(date), upper(date) | |
390 return lambda x: x >= start and x <= stop |