slashmili / python-jalali

Jalali calendar binding for Python based on Python's datetime module
http://pypi.python.org/pypi/jdatetime/
Other
343 stars 49 forks source link

ValueError: "day is out of range for month" when converting "2023-08-31 23:59:59" from Gregorian to Jalali #143

Closed shojaei-mohammad closed 1 year ago

shojaei-mohammad commented 1 year ago

Description: When attempting to convert the timestamp "2023-08-31 23:59:59" from Gregorian to Jalali using the jdatetime library, a ValueError is raised indicating "day is out of range for month". This issue persists even when the time is reduced by an hour to "2023-08-31 22:59:59".

Steps to reproduce: Below is the Python code which reproduces the issue:

python

import logging
from jdatetime import datetime as jdatetime

def convert_to_shamsi(created_at):
    print("this is passed value:", created_at)
    try:
        # Convert the string to a datetime object
        greg_date = jdatetime.strptime(created_at, "%Y-%m-%d %H:%M:%S")

        # Convert Gregorian date to Shamsi date
        shamsi_date = jdatetime.fromgregorian(datetime=greg_date)
        shamsi_year = shamsi_date.year
        shamsi_month = shamsi_date.month
        shamsi_day = shamsi_date.day
        shamsi_hour = str(shamsi_date.hour).zfill(2)
        shamsi_min = str(shamsi_date.minute).zfill(2)
    except ValueError as e:
        logging.error(
            "An error happened during the convert to shamsi, Error: {0}".format(e)
        )

    # Return the Shamsi date as a string
    shamsi_date_str = (
        f"{shamsi_year}/{shamsi_month}/{shamsi_day} - {shamsi_hour}:{shamsi_min}"
    )
    return shamsi_date_str

print(convert_to_shamsi("2023-08-31 23:59:59"))

Expected behavior: The script should successfully convert the Gregorian date "2023-08-31 23:59:59" to the corresponding Jalali date without raising a ValueError.

Actual behavior: The script raises a ValueError with the message "day is out of range for month".

5j9 commented 1 year ago

You are trying to parse a Gregorian date using jdatetime.strptime. That method is only supposed to handle Solar Hijri dates, not Gregorian dates. To convert the Gregorian date to Jalali try this:

>>> import datetime
>>> import jdatetime
>>> jdatetime.datetime.fromgregorian(date=datetime.datetime.fromisoformat("2023-08-31 23:59:59"))
jdatetime.datetime(1402, 6, 9, 23, 59, 59)

BTW, to convert the jdatetime back into a string, you might want to use strftime instead of implementing your own method:

>>> jdatetime.datetime(1402, 6, 9, 23, 59, 59).strftime('%Y/%-m/%-d %H:%M')
'1402/6/9 23:59'
shojaei-mohammad commented 1 year ago

Thank you for your answer, It solved my issue.