diff --git a/lingua_franca/format.py b/lingua_franca/format.py old mode 100755 new mode 100644 index 2e7d18d4..994a996e --- a/lingua_franca/format.py +++ b/lingua_franca/format.py @@ -28,7 +28,9 @@ get_full_lang_code, get_default_lang, get_default_loc, \ is_supported_full_lang, _raise_unsupported_language, \ UnsupportedLanguageError, NoneLangWarning, InvalidLangWarning, \ - FunctionNotLocalizedError, resolve_resource_file, FunctionNotLocalizedError + FunctionNotLocalizedError, resolve_resource_file, FunctionNotLocalizedError,\ + get_primary_lang_code +from lingua_franca.time import now_local _REGISTERED_FUNCTIONS = ("nice_number", @@ -380,6 +382,38 @@ def nice_date_time(dt, lang='', now=None, use_24hour=False, use_ampm) +@localized_function(run_own_code_on=[FunctionNotLocalizedError]) +def nice_day(dt, date_format='MDY', include_month=True, lang=""): + if include_month: + month = nice_month(dt, date_format, lang) + if date_format == 'MDY': + return "{} {}".format(month, dt.strftime("%d")) + else: + return "{} {}".format(dt.strftime("%d"), month) + return dt.strftime("%d") + + +@localized_function(run_own_code_on=[FunctionNotLocalizedError]) +def nice_weekday(dt, lang=""): + if lang in date_time_format.lang_config.keys(): + localized_day_names = list( + date_time_format.lang_config[lang]['weekday'].values()) + weekday = localized_day_names[dt.weekday()] + else: + weekday = dt.strftime("%A") + return weekday.capitalize() + + +@localized_function(run_own_code_on=[FunctionNotLocalizedError]) +def nice_month(dt, date_format='MDY', lang=""): + if lang in date_time_format.lang_config.keys(): + localized_month_names = date_time_format.lang_config[lang]['month'] + month = localized_month_names[str(int(dt.strftime("%m")))] + else: + month = dt.strftime("%B") + return month.capitalize() + + @localized_function(run_own_code_on=[UnsupportedLanguageError, FunctionNotLocalizedError]) def nice_year(dt, lang='', bc=False): """ @@ -403,6 +437,34 @@ def nice_year(dt, lang='', bc=False): return date_time_format.year_format(dt, full_code, bc) +@localized_function(run_own_code_on=[FunctionNotLocalizedError]) +def get_date_strings(dt=None, date_format='MDY', time_format="full", lang=""): + lang = get_primary_lang_code(lang) + dt = dt or now_local() + timestr = nice_time(dt, lang, speech=False, + use_24hour=time_format == "full") + monthstr = nice_month(dt, date_format, lang) + weekdaystr = nice_weekday(dt, lang) + yearstr = dt.strftime("%Y") + daystr = nice_day(dt, date_format, include_month=False, lang=lang) + if date_format == 'MDY': + dtstr = dt.strftime("%-m/%-d/%Y") + elif date_format == 'DMY': + dtstr = dt.strftime("%d/%-m/%-Y") + elif date_format == 'YMD': + dtstr = dt.strftime("%Y/%-m/%-d") + else: + raise ValueError("invalid date_format") + return { + "date_string": dtstr, + "time_string": timestr, + "month_string": monthstr, + "day_string": daystr, + 'year_string': yearstr, + "weekday_string": weekdaystr + } + + @localized_function(run_own_code_on=[FunctionNotLocalizedError]) def nice_duration(duration, lang='', speech=True): """ Convert duration in seconds to a nice spoken timespan diff --git a/lingua_franca/internal.py b/lingua_franca/internal.py index 3e389181..497c0db1 100644 --- a/lingua_franca/internal.py +++ b/lingua_franca/internal.py @@ -561,6 +561,14 @@ def _call_localized_function(func, *args, **kwargs): # If we didn't find a localized function to correspond with # the wrapped function, we cached NotImplementedError in its # place. + + # first account for the function not being present in any + # module, meaning all modules are falling back to a catch all + # parser, this usually means the function will need localization + # only in future languages not currently supported + if func_name not in _localized_functions[_module_name][lang_code]: + raise FunctionNotLocalizedError(func_name, lang_code) + loc_signature = _localized_functions[_module_name][lang_code][func_name] if isinstance(loc_signature, type(NotImplementedError())): raise loc_signature diff --git a/lingua_franca/time.py b/lingua_franca/time.py index 5ca5a920..463e0ab6 100644 --- a/lingua_franca/time.py +++ b/lingua_franca/time.py @@ -106,3 +106,16 @@ def to_system(dt): if not dt.tzinfo: dt = dt.replace(tzinfo=default_timezone()) return dt.astimezone(tz) + + +def is_leap_year(year): + return (year % 400 == 0) or ((year % 4 == 0) and (year % 100 != 0)) + + +def get_next_leap_year(year): + next_year = year + 1 + if is_leap_year(next_year): + return next_year + else: + return get_next_leap_year(next_year) +