Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
80475bb4
Commit
80475bb4
authored
Dec 25, 2002
by
Tim Peters
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented datetime.astimezone() and datetimetz.astimezone().
parent
6578dc92
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
159 additions
and
18 deletions
+159
-18
Doc/lib/libdatetime.tex
Doc/lib/libdatetime.tex
+22
-0
Lib/test/test_datetime.py
Lib/test/test_datetime.py
+53
-0
Modules/datetimemodule.c
Modules/datetimemodule.c
+84
-18
No files found.
Doc/lib/libdatetime.tex
View file @
80475bb4
...
...
@@ -601,6 +601,11 @@ Instance methods:
Return a datetime with the same value, except for those fields given
new values by whichever keyword arguments are specified.
- astimezone(tz)
Return a
\class
{
datetimetz
}
with the same date and time fields, and
with
\member
{
tzinfo
}
member
\var
{
tz
}
.
\var
{
tz
}
must be an instance
of a
\class
{
tzinfo
}
subclass.
- timetuple()
Return a 9-element tuple of the form returned by
\function
{
time.localtime()
}
.
...
...
@@ -1083,6 +1088,23 @@ Instance methods:
\code
{
tzinfo=None
}
can be specified to create a naive datetimetz from
an aware datetimetz.
- astimezone(tz)
Return a
\class
{
datetimetz
}
with new tzinfo member
\var
{
tz
}
.
\var
{
tz
}
must be an instance of a
\class
{
tzinfo
}
subclass. If self is naive, or
if
\code
(tz.utcoffset(self)
}
returns
\code
{
None
}
,
\code
{
self.astimezone(tz)
}
is equivalent to
\code
{
self.replace(tzinfo=tz)
}
: a new timezone object is attached
without any conversion of date or time fields. If self is aware and
\code
{
tz.utcoffset(self)
}
does not return
\code
{
None
}
, the date and
time fields are adjusted so that the result is local time in timezone
tz, representing the same UTC time as self.
\code
{
self.astimezone(tz)
}
is then equivalent to
\begin{verbatim}
(self - (self.utcoffset() - tz.utcoffset(self)).replace(tzinfo=tz)
\end{verbatim}
where the result of
\code
{
tz.uctcoffset(self)
}
is converted to a
\class
{
timedelta
}
if it's an integer.
- utcoffset()
If
\member
{
tzinfo
}
is
\code
{
None
}
, returns
\code
{
None
}
, else
\code
{
tzinfo.utcoffset(self)
}
converted to a
\class
{
timedelta
}
...
...
Lib/test/test_datetime.py
View file @
80475bb4
...
...
@@ -1295,6 +1295,21 @@ class TestDateTime(TestDate):
base
=
cls
(
2000
,
2
,
29
)
self
.
assertRaises
(
ValueError
,
base
.
replace
,
year
=
2001
)
def
test_astimezone
(
self
):
# Pretty boring for a datetime! datetimetz is more interesting here.
dt
=
self
.
theclass
.
now
()
f
=
FixedOffset
(
44
,
""
)
for
dtz
in
dt
.
astimezone
(
f
),
dt
.
astimezone
(
tz
=
f
):
self
.
failUnless
(
isinstance
(
dtz
,
datetimetz
))
self
.
assertEqual
(
dt
.
date
(),
dtz
.
date
())
self
.
assertEqual
(
dt
.
time
(),
dtz
.
time
())
self
.
failUnless
(
dtz
.
tzinfo
is
f
)
self
.
assertEqual
(
dtz
.
utcoffset
(),
timedelta
(
minutes
=
44
))
self
.
assertRaises
(
TypeError
,
dt
.
astimezone
)
# not enough args
self
.
assertRaises
(
TypeError
,
dt
.
astimezone
,
f
,
f
)
# too many args
self
.
assertRaises
(
TypeError
,
dt
.
astimezone
,
dt
)
# arg wrong type
class
TestTime
(
unittest
.
TestCase
):
...
...
@@ -2308,6 +2323,44 @@ class TestDateTimeTZ(TestDateTime, TZInfoBase):
base
=
cls
(
2000
,
2
,
29
)
self
.
assertRaises
(
ValueError
,
base
.
replace
,
year
=
2001
)
def
test_more_astimezone
(
self
):
# The inherited test_astimezone covered some trivial and error cases.
fnone
=
FixedOffset
(
None
,
"None"
)
f44m
=
FixedOffset
(
44
,
"44"
)
fm5h
=
FixedOffset
(
-
timedelta
(
hours
=
5
),
"m300"
)
dt
=
self
.
theclass
.
now
(
tzinfo
=
f44m
)
self
.
failUnless
(
dt
.
tzinfo
is
f44m
)
# Replacing with degenerate tzinfo doesn't do any adjustment.
for
x
in
dt
.
astimezone
(
fnone
),
dt
.
astimezone
(
tz
=
fnone
):
self
.
failUnless
(
x
.
tzinfo
is
fnone
)
self
.
assertEqual
(
x
.
date
(),
dt
.
date
())
self
.
assertEqual
(
x
.
time
(),
dt
.
time
())
# Ditt with None tz.
x
=
dt
.
astimezone
(
tz
=
None
)
self
.
failUnless
(
x
.
tzinfo
is
None
)
self
.
assertEqual
(
x
.
date
(),
dt
.
date
())
self
.
assertEqual
(
x
.
time
(),
dt
.
time
())
# Ditto replacing with same tzinfo.
x
=
dt
.
astimezone
(
dt
.
tzinfo
)
self
.
failUnless
(
x
.
tzinfo
is
f44m
)
self
.
assertEqual
(
x
.
date
(),
dt
.
date
())
self
.
assertEqual
(
x
.
time
(),
dt
.
time
())
# Replacing with different tzinfo does adjust.
got
=
dt
.
astimezone
(
fm5h
)
self
.
failUnless
(
got
.
tzinfo
is
fm5h
)
self
.
assertEqual
(
got
.
utcoffset
(),
timedelta
(
hours
=-
5
))
expected
=
dt
-
dt
.
utcoffset
()
# in effect, convert to UTC
expected
+=
fm5h
.
utcoffset
(
dt
)
# and from there to local time
expected
=
expected
.
replace
(
tzinfo
=
fm5h
)
# and attach new tzinfo
self
.
assertEqual
(
got
.
date
(),
expected
.
date
())
self
.
assertEqual
(
got
.
time
(),
expected
.
time
())
self
.
assertEqual
(
got
.
timetz
(),
expected
.
timetz
())
self
.
failUnless
(
got
.
tzinfo
is
expected
.
tzinfo
)
self
.
assertEqual
(
got
,
expected
)
def
test_suite
():
allsuites
=
[
unittest
.
makeSuite
(
klass
,
'test'
)
for
klass
in
(
TestModule
,
...
...
Modules/datetimemodule.c
View file @
80475bb4
...
...
@@ -600,6 +600,18 @@ get_tzinfo_member(PyObject *self)
return
tzinfo
;
}
/* self is a datetimetz. Replace its tzinfo member. */
void
replace_tzinfo
(
PyObject
*
self
,
PyObject
*
newtzinfo
)
{
assert
(
self
!=
NULL
);
assert
(
PyDateTimeTZ_Check
(
self
));
assert
(
check_tzinfo_subclass
(
newtzinfo
)
>=
0
);
Py_INCREF
(
newtzinfo
);
Py_DECREF
(((
PyDateTime_DateTimeTZ
*
)
self
)
->
tzinfo
);
((
PyDateTime_DateTimeTZ
*
)
self
)
->
tzinfo
=
newtzinfo
;
}
/* Internal helper.
* Call getattr(tzinfo, name)(tzinfoarg), and extract an int from the
* result. tzinfo must be an instance of the tzinfo class. If the method
...
...
@@ -2915,10 +2927,7 @@ datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
TIME_GET_MICROSECOND
(
time
));
if
(
result
&&
PyTimeTZ_Check
(
time
)
&&
PyDateTimeTZ_Check
(
result
))
{
/* Copy the tzinfo field. */
PyObject
*
tzinfo
=
((
PyDateTime_TimeTZ
*
)
time
)
->
tzinfo
;
Py_INCREF
(
tzinfo
);
Py_DECREF
(((
PyDateTime_DateTimeTZ
*
)
result
)
->
tzinfo
);
((
PyDateTime_DateTimeTZ
*
)
result
)
->
tzinfo
=
tzinfo
;
replace_tzinfo
(
result
,
((
PyDateTime_TimeTZ
*
)
time
)
->
tzinfo
);
}
return
result
;
}
...
...
@@ -3246,6 +3255,24 @@ datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
return
clone
;
}
static
PyObject
*
datetime_astimezone
(
PyDateTime_DateTime
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
PyObject
*
tzinfo
;
static
char
*
keywords
[]
=
{
"tz"
,
NULL
};
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kw
,
"O:astimezone"
,
keywords
,
&
tzinfo
))
return
NULL
;
if
(
check_tzinfo_subclass
(
tzinfo
)
<
0
)
return
NULL
;
return
new_datetimetz
(
GET_YEAR
(
self
),
GET_MONTH
(
self
),
GET_DAY
(
self
),
DATE_GET_HOUR
(
self
),
DATE_GET_MINUTE
(
self
),
DATE_GET_SECOND
(
self
),
DATE_GET_MICROSECOND
(
self
),
tzinfo
);
}
static
PyObject
*
datetime_timetuple
(
PyDateTime_DateTime
*
self
)
{
...
...
@@ -3397,6 +3424,9 @@ static PyMethodDef datetime_methods[] = {
{
"replace"
,
(
PyCFunction
)
datetime_replace
,
METH_KEYWORDS
,
PyDoc_STR
(
"Return datetime with new specified fields."
)},
{
"astimezone"
,
(
PyCFunction
)
datetime_astimezone
,
METH_KEYWORDS
,
PyDoc_STR
(
"tz -> datetimetz with same date & time, and tzinfo=tz
\n
"
)},
{
"__setstate__"
,
(
PyCFunction
)
datetime_setstate
,
METH_O
,
PyDoc_STR
(
"__setstate__(state)"
)},
...
...
@@ -4398,20 +4428,6 @@ static PyGetSetDef datetimetz_getset[] = {
* optional tzinfo argument.
*/
/* Internal helper.
* self is a datetimetz. Replace its tzinfo member.
*/
void
replace_tzinfo
(
PyObject
*
self
,
PyObject
*
newtzinfo
)
{
assert
(
self
!=
NULL
);
assert
(
newtzinfo
!=
NULL
);
assert
(
PyDateTimeTZ_Check
(
self
));
Py_INCREF
(
newtzinfo
);
Py_DECREF
(((
PyDateTime_DateTimeTZ
*
)
self
)
->
tzinfo
);
((
PyDateTime_DateTimeTZ
*
)
self
)
->
tzinfo
=
newtzinfo
;
}
static
char
*
datetimetz_kws
[]
=
{
"year"
,
"month"
,
"day"
,
"hour"
,
"minute"
,
"second"
,
"microsecond"
,
"tzinfo"
,
NULL
...
...
@@ -4696,6 +4712,53 @@ datetimetz_replace(PyDateTime_DateTimeTZ *self, PyObject *args, PyObject *kw)
return
clone
;
}
static
PyObject
*
datetimetz_astimezone
(
PyDateTime_DateTimeTZ
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
int
y
=
GET_YEAR
(
self
);
int
m
=
GET_MONTH
(
self
);
int
d
=
GET_DAY
(
self
);
int
hh
=
DATE_GET_HOUR
(
self
);
int
mm
=
DATE_GET_MINUTE
(
self
);
int
ss
=
DATE_GET_SECOND
(
self
);
int
us
=
DATE_GET_MICROSECOND
(
self
);
PyObject
*
tzinfo
;
static
char
*
keywords
[]
=
{
"tz"
,
NULL
};
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kw
,
"O:astimezone"
,
keywords
,
&
tzinfo
))
return
NULL
;
if
(
check_tzinfo_subclass
(
tzinfo
)
<
0
)
return
NULL
;
if
(
tzinfo
!=
Py_None
&&
self
->
tzinfo
!=
Py_None
)
{
int
none
;
int
selfoffset
;
selfoffset
=
call_utcoffset
(
self
->
tzinfo
,
(
PyObject
*
)
self
,
&
none
);
if
(
selfoffset
==
-
1
&&
PyErr_Occurred
())
return
NULL
;
if
(
!
none
)
{
int
tzoffset
;
tzoffset
=
call_utcoffset
(
tzinfo
,
(
PyObject
*
)
self
,
&
none
);
if
(
tzoffset
==
-
1
&&
PyErr_Occurred
())
return
NULL
;
if
(
!
none
)
{
mm
-=
selfoffset
-
tzoffset
;
if
(
normalize_datetime
(
&
y
,
&
m
,
&
d
,
&
hh
,
&
mm
,
&
ss
,
&
us
)
<
0
)
return
NULL
;
}
}
}
return
new_datetimetz
(
y
,
m
,
d
,
hh
,
mm
,
ss
,
us
,
tzinfo
);
}
static
PyObject
*
datetimetz_timetuple
(
PyDateTime_DateTimeTZ
*
self
)
{
...
...
@@ -4908,6 +4971,9 @@ static PyMethodDef datetimetz_methods[] = {
{
"replace"
,
(
PyCFunction
)
datetimetz_replace
,
METH_KEYWORDS
,
PyDoc_STR
(
"Return datetimetz with new specified fields."
)},
{
"astimezone"
,
(
PyCFunction
)
datetimetz_astimezone
,
METH_KEYWORDS
,
PyDoc_STR
(
"tz -> convert to local time in new timezone tz
\n
"
)},
{
"__setstate__"
,
(
PyCFunction
)
datetimetz_setstate
,
METH_O
,
PyDoc_STR
(
"__setstate__(state)"
)},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment