Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
fc070d27
Kaydet (Commit)
fc070d27
authored
Mar 15, 2008
tarafından
Skip Montanaro
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
add %f format to datetime - issue 1158
üst
75e51680
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
145 additions
and
50 deletions
+145
-50
datetime.rst
Doc/library/datetime.rst
+42
-11
_strptime.py
Lib/_strptime.py
+15
-6
test_datetime.py
Lib/test/test_datetime.py
+9
-8
test_strptime.py
Lib/test/test_strptime.py
+0
-0
datetimemodule.c
Modules/datetimemodule.c
+78
-24
timemodule.c
Modules/timemodule.c
+1
-1
No files found.
Doc/library/datetime.rst
Dosyayı görüntüle @
fc070d27
...
...
@@ -1489,9 +1489,31 @@ For :class:`time` objects, the format codes for year, month, and day should not
be used, as time objects have no such values. If they're used anyway, ``1900``
is substituted for the year, and ``0`` for the month and day.
For :class:`date` objects, the format codes for hours, minutes, and seconds
should not be used, as :class:`date` objects have no such values. If they're
used anyway, ``0`` is substituted for them.
For :class:`date` objects, the format codes for hours, minutes, seconds, and
microseconds should not be used, as :class:`date` objects have no such
values. If they're used anyway, ``0`` is substituted for them.
:class:`time` and :class:`datetime` objects support a ``%f`` format code
which expands to the number of microseconds in the object, zero-padded on
the left to six places.
.. versionadded:: 2.6
For a naive object, the ``%z`` and ``%Z`` format codes are replaced by empty
strings.
For an aware object:
``%z``
:meth:`utcoffset` is transformed into a 5-character string of the form +HHMM or
-HHMM, where HH is a 2-digit string giving the number of UTC offset hours, and
MM is a 2-digit string giving the number of UTC offset minutes. For example, if
:meth:`utcoffset` returns ``timedelta(hours=-3, minutes=-30)``, ``%z`` is
replaced with the string ``'-0330'``.
``%Z``
If :meth:`tzname` returns ``None``, ``%Z`` is replaced by an empty string.
Otherwise ``%Z`` is replaced by the returned value, which must be a string.
The full set of format codes supported varies across platforms, because Python
calls the platform C library's :func:`strftime` function, and platform
...
...
@@ -1524,6 +1546,10 @@ platforms. Regardless of platform, years before 1900 cannot be used.
| ``%d`` | Day of the month as a decimal | |
| | number [01,31]. | |
+-----------+--------------------------------+-------+
| ``%f`` | Microsecond as a decimal | \(1) |
| | number [0,999999], zero-padded | |
| | on the left | |
+-----------+--------------------------------+-------+
| ``%H`` | Hour (24-hour clock) as a | |
| | decimal number [00,23]. | |
+-----------+--------------------------------+-------+
...
...
@@ -1539,13 +1565,13 @@ platforms. Regardless of platform, years before 1900 cannot be used.
| ``%M`` | Minute as a decimal number | |
| | [00,59]. | |
+-----------+--------------------------------+-------+
| ``%p`` | Locale's equivalent of either | \(
1
) |
| ``%p`` | Locale's equivalent of either | \(
2
) |
| | AM or PM. | |
+-----------+--------------------------------+-------+
| ``%S`` | Second as a decimal number | \(
2
) |
| ``%S`` | Second as a decimal number | \(
3
) |
| | [00,61]. | |
+-----------+--------------------------------+-------+
| ``%U`` | Week number of the year | \(
3
) |
| ``%U`` | Week number of the year | \(
4
) |
| | (Sunday as the first day of | |
| | the week) as a decimal number | |
| | [00,53]. All days in a new | |
...
...
@@ -1556,7 +1582,7 @@ platforms. Regardless of platform, years before 1900 cannot be used.
| ``%w`` | Weekday as a decimal number | |
| | [0(Sunday),6]. | |
+-----------+--------------------------------+-------+
| ``%W`` | Week number of the year | \(
3
) |
| ``%W`` | Week number of the year | \(
4
) |
| | (Monday as the first day of | |
| | the week) as a decimal number | |
| | [00,53]. All days in a new | |
...
...
@@ -1576,7 +1602,7 @@ platforms. Regardless of platform, years before 1900 cannot be used.
| ``%Y`` | Year with century as a decimal | |
| | number. | |
+-----------+--------------------------------+-------+
| ``%z`` | UTC offset in the form +HHMM | \(
4
) |
| ``%z`` | UTC offset in the form +HHMM | \(
5
) |
| | or -HHMM (empty string if the | |
| | the object is naive). | |
+-----------+--------------------------------+-------+
...
...
@@ -1589,17 +1615,22 @@ platforms. Regardless of platform, years before 1900 cannot be used.
Notes:
(1)
When used with the :func:`strptime` function, the ``%f`` directive
accepts from one to six digits and zero pads on the right. ``%f`` is
an extension to the set of format characters in the C standard.
(2)
When used with the :func:`strptime` function, the ``%p`` directive only affects
the output hour field if the ``%I`` directive is used to parse the hour.
(
2
)
(
3
)
The range really is ``0`` to ``61``; this accounts for leap seconds and the
(very rare) double leap seconds.
(
3
)
(
4
)
When used with the :func:`strptime` function, ``%U`` and ``%W`` are only used in
calculations when the day of the week and the year are specified.
(
4
)
(
5
)
For example, if :meth:`utcoffset` returns ``timedelta(hours=-3, minutes=-30)``,
``%z`` is replaced with the string ``'-0330'``.
Lib/_strptime.py
Dosyayı görüntüle @
fc070d27
...
...
@@ -22,7 +22,7 @@ try:
except
:
from
dummy_thread
import
allocate_lock
as
_thread_allocate_lock
__all__
=
[
'strptime'
]
__all__
=
[]
def
_getlang
():
# Figure out what the current language is set to.
...
...
@@ -190,6 +190,7 @@ class TimeRE(dict):
base
.
__init__
({
# The " \d" part of the regex is to make %c from ANSI C work
'd'
:
r"(?P<d>3[0-1]|[1-2]\d|0[1-9]|[1-9]| [1-9])"
,
'f'
:
r"(?P<f>[0-9]{1,6})"
,
'H'
:
r"(?P<H>2[0-3]|[0-1]\d|\d)"
,
'I'
:
r"(?P<I>1[0-2]|0[1-9]|[1-9])"
,
'j'
:
r"(?P<j>36[0-6]|3[0-5]\d|[1-2]\d\d|0[1-9]\d|00[1-9]|[1-9]\d|0[1-9]|[1-9])"
,
...
...
@@ -291,7 +292,7 @@ def _calc_julian_from_U_or_W(year, week_of_year, day_of_week, week_starts_Mon):
return
1
+
days_to_week
+
day_of_week
def
strptime
(
data_string
,
format
=
"
%
a
%
b
%
d
%
H:
%
M:
%
S
%
Y"
):
def
_
strptime
(
data_string
,
format
=
"
%
a
%
b
%
d
%
H:
%
M:
%
S
%
Y"
):
"""Return a time struct based on the input string and the format string."""
global
_TimeRE_cache
,
_regex_cache
with
_cache_lock
:
...
...
@@ -327,7 +328,7 @@ def strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
data_string
[
found
.
end
():])
year
=
1900
month
=
day
=
1
hour
=
minute
=
second
=
0
hour
=
minute
=
second
=
fraction
=
0
tz
=
-
1
# Default to -1 to signify that values not known; not critical to have,
# though
...
...
@@ -384,6 +385,11 @@ def strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
minute
=
int
(
found_dict
[
'M'
])
elif
group_key
==
'S'
:
second
=
int
(
found_dict
[
'S'
])
elif
group_key
==
'f'
:
s
=
found_dict
[
'f'
]
# Pad to always return microseconds.
s
+=
"0"
*
(
6
-
len
(
s
))
fraction
=
int
(
s
)
elif
group_key
==
'A'
:
weekday
=
locale_time
.
f_weekday
.
index
(
found_dict
[
'A'
]
.
lower
())
elif
group_key
==
'a'
:
...
...
@@ -440,6 +446,9 @@ def strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
day
=
datetime_result
.
day
if
weekday
==
-
1
:
weekday
=
datetime_date
(
year
,
month
,
day
)
.
weekday
()
return
time
.
struct_time
((
year
,
month
,
day
,
hour
,
minute
,
second
,
weekday
,
julian
,
tz
))
return
(
time
.
struct_time
((
year
,
month
,
day
,
hour
,
minute
,
second
,
weekday
,
julian
,
tz
)),
fraction
)
def
_strptime_time
(
data_string
,
format
=
"
%
a
%
b
%
d
%
H:
%
M:
%
S
%
Y"
):
return
_strptime
(
data_string
,
format
)[
0
]
Lib/test/test_datetime.py
Dosyayı görüntüle @
fc070d27
...
...
@@ -1507,11 +1507,12 @@ class TestDateTime(TestDate):
self
.
failUnless
(
abs
(
from_timestamp
-
from_now
)
<=
tolerance
)
def
test_strptime
(
self
):
import
time
import
_strp
time
string
=
'2004-12-01 13:02:47'
format
=
'
%
Y-
%
m-
%
d
%
H:
%
M:
%
S'
expected
=
self
.
theclass
(
*
(
time
.
strptime
(
string
,
format
)[
0
:
6
]))
string
=
'2004-12-01 13:02:47.197'
format
=
'
%
Y-
%
m-
%
d
%
H:
%
M:
%
S.
%
f'
result
,
frac
=
_strptime
.
_strptime
(
string
,
format
)
expected
=
self
.
theclass
(
*
(
result
[
0
:
6
]
+
(
frac
,)))
got
=
self
.
theclass
.
strptime
(
string
,
format
)
self
.
assertEqual
(
expected
,
got
)
...
...
@@ -1539,9 +1540,9 @@ class TestDateTime(TestDate):
def
test_more_strftime
(
self
):
# This tests fields beyond those tested by the TestDate.test_strftime.
t
=
self
.
theclass
(
2004
,
12
,
31
,
6
,
22
,
33
)
self
.
assertEqual
(
t
.
strftime
(
"
%
m
%
d
%
y
%
S
%
M
%
H
%
j"
),
"12 31 04 33 22 06 366"
)
t
=
self
.
theclass
(
2004
,
12
,
31
,
6
,
22
,
33
,
47
)
self
.
assertEqual
(
t
.
strftime
(
"
%
m
%
d
%
y
%
f
%
S
%
M
%
H
%
j"
),
"12 31 04
000047
33 22 06 366"
)
def
test_extract
(
self
):
dt
=
self
.
theclass
(
2002
,
3
,
4
,
18
,
45
,
3
,
1234
)
...
...
@@ -1814,7 +1815,7 @@ class TestTime(HarmlessMixedComparison, unittest.TestCase):
def
test_strftime
(
self
):
t
=
self
.
theclass
(
1
,
2
,
3
,
4
)
self
.
assertEqual
(
t
.
strftime
(
'
%
H
%
M
%
S
'
),
"01 02 03
"
)
self
.
assertEqual
(
t
.
strftime
(
'
%
H
%
M
%
S
%
f'
),
"01 02 03 000004
"
)
# A naive object replaces %z and %Z with empty strings.
self
.
assertEqual
(
t
.
strftime
(
"'
%
z' '
%
Z'"
),
"'' ''"
)
...
...
Lib/test/test_strptime.py
Dosyayı görüntüle @
fc070d27
This diff is collapsed.
Click to expand it.
Modules/datetimemodule.c
Dosyayı görüntüle @
fc070d27
...
...
@@ -1130,10 +1130,24 @@ format_utcoffset(char *buf, size_t buflen, const char *sep,
return
0
;
}
static
PyObject
*
make_freplacement
(
PyObject
*
object
)
{
char
freplacement
[
7
];
if
(
PyTime_Check
(
object
))
sprintf
(
freplacement
,
"%06d"
,
TIME_GET_MICROSECOND
(
object
));
else
if
(
PyDateTime_Check
(
object
))
sprintf
(
freplacement
,
"%06d"
,
DATE_GET_MICROSECOND
(
object
));
else
sprintf
(
freplacement
,
"%06d"
,
0
);
return
PyString_FromStringAndSize
(
freplacement
,
strlen
(
freplacement
));
}
/* I sure don't want to reproduce the strftime code from the time module,
* so this imports the module and calls it. All the hair is due to
* giving special meanings to the %z
and %Z format codes via a preprocessing
* step on the format string.
* giving special meanings to the %z
, %Z and %f format codes via a
*
preprocessing
step on the format string.
* tzinfoarg is the argument to pass to the object's tzinfo method, if
* needed.
*/
...
...
@@ -1145,6 +1159,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
PyObject
*
zreplacement
=
NULL
;
/* py string, replacement for %z */
PyObject
*
Zreplacement
=
NULL
;
/* py string, replacement for %Z */
PyObject
*
freplacement
=
NULL
;
/* py string, replacement for %f */
char
*
pin
;
/* pointer to next char in input format */
char
ch
;
/* next char in input format */
...
...
@@ -1186,11 +1201,11 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
}
}
/* Scan the input format, looking for %z
and %Z
escapes, building
/* Scan the input format, looking for %z
/%Z/%f
escapes, building
* a new format. Since computing the replacements for those codes
* is expensive, don't unless they're actually used.
*/
totalnew
=
PyString_Size
(
format
)
+
1
;
/* realistic if no %z/%Z */
totalnew
=
PyString_Size
(
format
)
+
1
;
/* realistic if no %z/%Z
/%f
*/
newfmt
=
PyString_FromStringAndSize
(
NULL
,
totalnew
);
if
(
newfmt
==
NULL
)
goto
Done
;
pnew
=
PyString_AsString
(
newfmt
);
...
...
@@ -1272,6 +1287,18 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
ptoappend
=
PyString_AS_STRING
(
Zreplacement
);
ntoappend
=
PyString_GET_SIZE
(
Zreplacement
);
}
else
if
(
ch
==
'f'
)
{
/* format microseconds */
if
(
freplacement
==
NULL
)
{
freplacement
=
make_freplacement
(
object
);
if
(
freplacement
==
NULL
)
goto
Done
;
}
assert
(
freplacement
!=
NULL
);
assert
(
PyString_Check
(
freplacement
));
ptoappend
=
PyString_AS_STRING
(
freplacement
);
ntoappend
=
PyString_GET_SIZE
(
freplacement
);
}
else
{
/* percent followed by neither z nor Z */
ptoappend
=
pin
-
2
;
...
...
@@ -1313,6 +1340,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Py_DECREF
(
time
);
}
Done:
Py_XDECREF
(
freplacement
);
Py_XDECREF
(
zreplacement
);
Py_XDECREF
(
Zreplacement
);
Py_XDECREF
(
newfmt
);
...
...
@@ -3853,43 +3881,69 @@ datetime_utcfromtimestamp(PyObject *cls, PyObject *args)
static
PyObject
*
datetime_strptime
(
PyObject
*
cls
,
PyObject
*
args
)
{
PyObject
*
result
=
NULL
,
*
obj
,
*
module
;
static
PyObject
*
module
=
NULL
;
PyObject
*
result
=
NULL
,
*
obj
,
*
st
=
NULL
,
*
frac
=
NULL
;
const
char
*
string
,
*
format
;
if
(
!
PyArg_ParseTuple
(
args
,
"ss:strptime"
,
&
string
,
&
format
))
return
NULL
;
if
((
module
=
PyImport_ImportModuleNoBlock
(
"time"
))
==
NULL
)
if
(
module
==
NULL
&&
(
module
=
PyImport_ImportModuleNoBlock
(
"_strptime"
))
==
NULL
)
return
NULL
;
obj
=
PyObject_CallMethod
(
module
,
"strptime"
,
"ss"
,
string
,
format
);
Py_DECREF
(
module
);
/* _strptime._strptime returns a two-element tuple. The first
element is a time.struct_time object. The second is the
microseconds (which are not defined for time.struct_time). */
obj
=
PyObject_CallMethod
(
module
,
"_strptime"
,
"ss"
,
string
,
format
);
if
(
obj
!=
NULL
)
{
int
i
,
good_timetuple
=
1
;
long
int
ia
[
6
];
if
(
PySequence_Check
(
obj
)
&&
PySequence_Size
(
obj
)
>=
6
)
for
(
i
=
0
;
i
<
6
;
i
++
)
{
PyObject
*
p
=
PySequence_GetItem
(
obj
,
i
);
if
(
p
==
NULL
)
{
Py_DECREF
(
obj
);
return
NULL
;
long
int
ia
[
7
];
if
(
PySequence_Check
(
obj
)
&&
PySequence_Size
(
obj
)
==
2
)
{
st
=
PySequence_GetItem
(
obj
,
0
);
frac
=
PySequence_GetItem
(
obj
,
1
);
if
(
st
==
NULL
||
frac
==
NULL
)
good_timetuple
=
0
;
/* copy y/m/d/h/m/s values out of the
time.struct_time */
if
(
good_timetuple
&&
PySequence_Check
(
st
)
&&
PySequence_Size
(
st
)
>=
6
)
{
for
(
i
=
0
;
i
<
6
;
i
++
)
{
PyObject
*
p
=
PySequence_GetItem
(
st
,
i
);
if
(
p
==
NULL
)
{
good_timetuple
=
0
;
break
;
}
if
(
PyInt_Check
(
p
))
ia
[
i
]
=
PyInt_AsLong
(
p
);
else
good_timetuple
=
0
;
Py_DECREF
(
p
);
}
if
(
PyInt_Check
(
p
))
ia
[
i
]
=
PyInt_AsLong
(
p
);
else
good_timetuple
=
0
;
Py_DECREF
(
p
);
}
else
good_timetuple
=
0
;
/* follow that up with a little dose of microseconds */
if
(
PyInt_Check
(
frac
))
ia
[
6
]
=
PyInt_AsLong
(
frac
);
else
good_timetuple
=
0
;
}
else
good_timetuple
=
0
;
if
(
good_timetuple
)
result
=
PyObject_CallFunction
(
cls
,
"iiiiii"
,
ia
[
0
],
ia
[
1
],
ia
[
2
],
ia
[
3
],
ia
[
4
],
ia
[
5
]);
result
=
PyObject_CallFunction
(
cls
,
"iiiiiii"
,
ia
[
0
],
ia
[
1
],
ia
[
2
],
ia
[
3
],
ia
[
4
],
ia
[
5
],
ia
[
6
]);
else
PyErr_SetString
(
PyExc_ValueError
,
"unexpected value from time.strptime"
);
Py_DECREF
(
obj
);
"unexpected value from _strptime._strptime"
);
}
Py_XDECREF
(
obj
);
Py_XDECREF
(
st
);
Py_XDECREF
(
frac
);
return
result
;
}
...
...
Modules/timemodule.c
Dosyayı görüntüle @
fc070d27
...
...
@@ -520,7 +520,7 @@ time_strptime(PyObject *self, PyObject *args)
if
(
!
strptime_module
)
return
NULL
;
strptime_result
=
PyObject_CallMethod
(
strptime_module
,
"
strp
time"
,
"O"
,
args
);
strptime_result
=
PyObject_CallMethod
(
strptime_module
,
"
_strptime_
time"
,
"O"
,
args
);
Py_DECREF
(
strptime_module
);
return
strptime_result
;
}
...
...
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