byteverse / chronos

Haskell time library focusing on performance
Other
54 stars 22 forks source link

Add Datetime formatter that shows month in english #30

Closed chshersh closed 4 years ago

chshersh commented 5 years ago

Currently I can use builder_DmyHMS to see the time like this:

05-05-2019 11:27:43.252

It would be nice to be able to format month in English (3 letters is enough), so I can see:

05 May 2019 11:27:43.252 +00:00
chessai commented 5 years ago

I agree that this would be useful. @andrewthad what do you think?

andrewthad commented 5 years ago

Yeah, I have no problem with supporting this. I wouldn’t want to hardcode the localization though, so the function would need to take a MonthMatch as an argument. This would let people pick month names in languages other than English.

lucazulian commented 5 years ago

In order to simplify the implementation of builder_DmyHMS we would like to enrich date time configuration with other options. Our first proposal could be something like:

data DatetimeFormat = DatetimeFormat
  { datetimeFormatDateSeparator :: !(Maybe Char)
    -- ^ Separator in the date
  , datetimeFormatSeparator :: !(Maybe Char)
    -- ^ Separator between date and time
  , datetimeFormatTimeSeparator :: !(Maybe Char)
    -- ^ Separator in the time
  , datetimeFormatDaysOfWeek :: !(DaysOfWeekFormat)
    -- ^ How to display the day of the week
  , datetimeFormatMonth :: !(MonthFormat)
    -- ^ How to display the month
  } deriving (Show,Read,Eq,Ord)

data DaysOfWeekFormat
  = None
  | Full
  | Abbreviated

data MonthFormat
  = Full
  | Abbrevited
  | Number

With this configuration we describe in which mode format the Datetime or OffsetDatetime types. We could go further, so let we know which direction we should proceed.

Open Source Saturday

chessai commented 5 years ago

I've not thought about the best way to proceed really, but I'm certain @chshersh and @andrewthad will have some good ideas. I may have some later. (Sorry for the apparent uselessness right now)

lucazulian commented 5 years ago

@chessai sorry, but do you have thought about the best way to proceed?

chessai commented 5 years ago

@lucazulian that wouldn't be the right approach, i don't think. it's possible that we could implement builder functions that also take a MonthMatch BB.Builder, that way we achieve the same flexibility without introducing new types/disrupting the API. See Chronos.Locale.English for an example of the MonthMatch which @chshersh would be interested in.

lucazulian commented 5 years ago

@chessai sorry, do you have some news?

chessai commented 5 years ago

I thought my previous comment covered all bases, what am i not seeing? Sorry. On the subway right now. Will take a closer look in a moment.

chessai commented 5 years ago

i think we should augment DatetimeFormat:

data DatetimeFormat = DatetimeFormat
  { ... currently existing fields ...
  , monthFormatter :: !(MonthMatch BB.Builder)
  }

and have a defaultDatetimeFormat:

defaultDatetimeFormat :: DatetimeFormat
defaultDatetimeFormat = DatetimeFormat
  Nothing
  Nothing
  Nothing
  (buildMonthMatch "01" "02" "03" "04" "05" "06" "07" "08" "09" "10" "11" "12")
chessai commented 5 years ago

This would definitely be a breaking change, but perhaps useful? i'm beginning to loathe the idea of adding more and more functions that take different datatypes for ways people would like to format time.

chshersh commented 5 years ago

Any progress on this?

chessai commented 4 years ago

Not yet, but i think my previous comment about DatetimeFormat is the way to go. Thoughts @andrewthad @chshersh?

andrewthad commented 4 years ago

Currently, DatetimeFormat includes three fields: a ymd separator, a day-time separator, and a time separator. By adding localization for of the month to this type, it starts to edge into new territory. What about AM-PM encoding? What about day-of-week encoding? Conceivably, those could go in that type as well. We could just have one big localization type. And that is precisely what the time library does, calling the type TimeLocale. But it can go even further. What about day-of-month and hour and minute? Sometimes, people want a zero-padded 05, and sometimes they want 5. This too could be handled by the same mechanism. And we could throw in the subsecond stuff as well. There could just be one big universal function for datetime encoding with a single locale argument, and it could handle all of the cases currently handled, and I think this would work out. And the existing functions could be reimplemented in terms of the new function so that this wouldn't be a breaking change. Hopefully, this would not regress performance. I think it would work out alright.

Decoding is a slightly different story. People often like permissive decoding. It may be trickier to unify all of these under one grand scheme.

chshersh commented 4 years ago

Localisation is difficult. A single person can't implement localisation for each language and each format. So unless somebody is going to spend a ton of money and developers time on this problem, I don't think that full generalisation is a way to go. I want to format the date like this:

05 May 2019 11:27:43.252 +00:00

And any minimal working solution is fine for me. Honestly, at this moment I'm even okay with allocating a temporary mutable array of predefined size (size is statically known in my case, it's always 31 bytes), filling it with data in the format I want and forget about this problem for several years. But this requires the library to expose all fields of the time in a friendly way. Currently, Time is Int64 which doesn't make it very convenient to extract a day, month, year, hours, minutes, seconds, sub-seconds and timezone.

So the alternative solution could be to provide the following function instead of patching formatting data type:

timeParts :: Time -> TimeParts

data TimeParts = TimeParts
    { timePartsDay :: Int
    , timePartsMonth :: MonthEnum
    , timePartsYear :: Int
    , timePartsHour :: Int
    , timePartsMinute :: Int
    , timePartsSecond :: Int
    , timePartsSubsecond :: Int
    , timePartsTimezoneOffset :: Int
    }
chessai commented 4 years ago

@chshersh I think I agree with this. I have definitely been annoyed at the sort of 'recursive unpacking' that chronos admits.

chessai commented 4 years ago

Okay, I think the suggested deconstruction is the best and simplest route for now. I am going to do this if no one had a problem with it. @andrewthad?

On Fri, Nov 8, 2019, 10:11 AM Dmitrii Kovanikov notifications@github.com wrote:

Localisation is difficult. A single person can't implement localisation for each language and each format. So unless somebody is going to spend a ton of money and developers time on this problem, I don't think that full generalisation is a way to go. I want to format the date like this:

05 May 2019 11:27:43.252 +00:00

And any minimal working solution is fine for me. Honestly, at this moment I'm even okay with allocating a temporary mutable array of predefined size (size is statically known in my case, it's always 31 bytes), filling it with data in the format I want and forget about this problem for several years. But this requires the library to expose all fields of the time in a friendly way. Currently, Time is Int64 which doesn't make it very convenient to extract a day, month, year, hours, minutes, seconds, sub-seconds and timezone.

So the alternative solution could be to provide the following function instead of patching formatting data type:

timeParts :: Time -> TimeParts data TimeParts = TimeParts { timePartsDay :: Int , timePartsMonth :: MonthEnum , timePartsYear :: Int , timePartsHour :: Int , timePartsMinute :: Int , timePartsSecond :: Int , timePartsSubsecond :: Int , timePartsTimezoneOffset :: Int }

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/andrewthad/chronos/issues/30?email_source=notifications&email_token=AEOIX2YQKX5PUMLH2C5VVW3QSV6Q5A5CNFSM4HK3BAHKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEDSMWII#issuecomment-551865121, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEOIX23C2E2WCRUBB6S3PR3QSV6Q5ANCNFSM4HK3BAHA .

chessai commented 4 years ago

released at 1.0.9

chessai commented 4 years ago

thanks @chshersh and @lucazulian for your continued support and interest.