Skip to content

Undocumented behavior in strptime for ISO week dates #90750

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
JonatanSkogsfors mannequin opened this issue Jan 31, 2022 · 8 comments
Closed

Undocumented behavior in strptime for ISO week dates #90750

JonatanSkogsfors mannequin opened this issue Jan 31, 2022 · 8 comments
Labels
3.11 only security fixes 3.12 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@JonatanSkogsfors
Copy link
Mannequin

JonatanSkogsfors mannequin commented Jan 31, 2022

BPO 46592
Nosy @abalkin, @jonatanskogsfors, @pganssle

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = None
created_at = <Date 2022-01-31.13:06:25.880>
labels = ['type-bug', 'library', '3.10']
title = 'Undocumented behavior in strptime for ISO week dates'
updated_at = <Date 2022-01-31.13:18:52.284>
user = 'https://github.com/jonatanskogsfors'

bugs.python.org fields:

activity = <Date 2022-01-31.13:18:52.284>
actor = 'AlexWaygood'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Library (Lib)']
creation = <Date 2022-01-31.13:06:25.880>
creator = 'Jonatan Skogsfors'
dependencies = []
files = []
hgrepos = []
issue_num = 46592
keywords = []
message_count = 1.0
messages = ['412200']
nosy_count = 3.0
nosy_names = ['belopolsky', 'Jonatan Skogsfors', 'p-ganssle']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue46592'
versions = ['Python 3.10']

Linked PRs

@JonatanSkogsfors
Copy link
Mannequin Author

JonatanSkogsfors mannequin commented Jan 31, 2022

Consider the following code :
Python 3.10.2 (main, Jan 31 2022, 12:03:48) [GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from datetime import datetime
>>> datetime.strptime("2021-53-1", "%Y-%W-%w").strftime("%c")
'Mon Jan  3 00:00:00 2022'

And also:
>>> datetime.strptime("2021-53-1", "%G-%V-%u").strftime("%c")
'Mon Jan  3 00:00:00 2022'

2021 is a "short year" with 52 weeks (e.g. since December 31 is on a Friday). The 53rd week of 2021 is interpreted by Python as week 1 of 2022. This can be convenient but as I understand it, it is not a part of ISO 8601 and it is not documented as a deviation in the documentation for datetime.

As a comparison, the special behavior of week 0 (also not part of ISO 8601) is documented. In the documentation for format directive "%W" it is stated that "All days in a new year preceding the first Monday are considered to be in week 0."

If the behavior for week 53 is intended (as opposed to raising an error) I think it should be documented.

@JonatanSkogsfors JonatanSkogsfors mannequin added 3.10 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels Jan 31, 2022
@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
@Ev2geny
Copy link
Contributor

Ev2geny commented Oct 7, 2022

There is another function in the datetime module: fromisocalendar(), it works as expected:

import datetime

print(datetime.date.fromisocalendar(2021, 53, 1))
# ValueError: Invalid week: 53

print(datetime.datetime.fromisocalendar(2021, 53, 1))
# ValueError: Invalid week: 53

But the fromisocalendar() was added later, in release 3.8 and by a different person, than original code.

So, we have a situation , that constructing datetime from year, week and day of the week is present both in 'strptime' and in fromisocalendar, but function differently

Interesting, that other similar packages from standard libraries of Java, C# and C also do not complain about none-existing week 53. It looks like they all have taken a decision not to check the week number (unlike with the month day). I am not sure why such decision was taken.

C#

// https://weeknumber.com/how-to/c-sharp
Console.WriteLine(System.Globalization.ISOWeek.ToDateTime(2021, 53, DayOfWeek.Monday));

// 03-Jan-2022 00:00:00

Java

package com.company;

import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;

public class Main {

    public static void main(String[] args) {
	// https://weeknumber.com/how-to/java

        GregorianCalendar calendar = new GregorianCalendar();
        calendar.setFirstDayOfWeek(GregorianCalendar.MONDAY);
        calendar.setMinimalDaysInFirstWeek(4);

        calendar.setWeekDate(2021, 53, GregorianCalendar.MONDAY);

        SimpleDateFormat sdf1 = new SimpleDateFormat("d-MMM-y");
        System.out.println(sdf1.format(calendar.getTime()));
        // 3-Jan-2022


        // However
        System.out.println(calendar.get(GregorianCalendar.WEEK_OF_YEAR));
       // 1
    }
}

And C (tested under Ubuntu) got it totally wrong

       // https://man7.org/linux/man-pages/man3/strptime.3.html
       
       #define _XOPEN_SOURCE
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>
       #include <time.h>

       int
       main(void)
       {
           struct tm tm;
           char buf[255];

           memset(&tm, 0, sizeof(tm));
           strptime("Y2021 W53 D1", "Y%Y W%OW D%w", &tm);
           strftime(buf, sizeof(buf), "%d %b %Y %H:%M", &tm);
           puts(buf);
           
          // !!!!!     34 Dec 2021 00:00


           exit(EXIT_SUCCESS);
       }

@Ev2geny
Copy link
Contributor

Ev2geny commented Oct 9, 2022

So, I guess someone needs to take a decision whether the functionality of strptime is a bug or a feature and either to fix it or document.

@encukou
Copy link
Member

encukou commented Oct 10, 2022

datetime experts @pganssle & @abalkin, do you have opinions here?

@Ev2geny
Copy link
Contributor

Ev2geny commented Oct 20, 2022

@pganssle & @abalkin , just a kind reminder. Do you have any opinion on this subject?

@pganssle
Copy link
Member

I think we can probably fix this, since the ISO parsing code is happening on our side. Maybe we can replace this section of _strptime with a datetime.fromisocalendar call?

@merwok merwok added 3.11 only security fixes 3.12 only security fixes and removed 3.10 only security fixes labels Apr 24, 2023
@pganssle
Copy link
Member

OK, this seems like a pretty simple fix, I've created a PR for it: #103802

pganssle added a commit that referenced this issue Apr 27, 2023
Use datetime.fromisocalendar in _strptime

This unifies the ISO → Gregorian conversion logic and improves handling
of invalid ISO weeks.
@hauntsaninja
Copy link
Contributor

Looks like the fix was merged, thanks all!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.11 only security fixes 3.12 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
Projects
Archived in project
Development

No branches or pull requests

5 participants