Expose functions needed to create `ParseTime` instances
ygale opened this issue · comments
I need to create ParseTime
instances for some types in the timezone-series library. For that, it appears I need the timeParseTimeSpecifier
function, and preferably also the timeSubstituteTimeSpecifier
function. These exist in the time library, but they are hidden. Please expose them - even if only in an Internal
module.
There does not appear to be any reasonable way to write good quality instances without these functions.
See ygale/timezone-olson#11 and ygale/timezone-series#11
EDIT: Updated to make the ask more explicit and clear.
@AshleyYakeley ping
Is the recommended way to copy/paste the source code of these functions? That doesn't seem like a great idea.
Could you please expose these functions (even if only in an Internal
module)? Thanks.
Hmm I guess for now I could just re-use the implementation of parseTimeSpecifier
and substituteTimeSpecifier
from the TimeZone
instance. Because for now the ParseTime
instance of TimeZoneSeries
can only build a trivial series with a single timezone.
Still a hack, but not nearly as bad as cut-and-paste of the those entire function bodies.
In principle, though, shouldn't these functions be exposed? Note that for your own instances you always use these directly; you do not copy them from other instances. If that is best practice, shouldn't new instances built by external libraries be allowed to do the same?
TBH I wasn't really expecting other people to create their own ParseTime
or FormatTime
instances?
What are the types you want instances for?
(and also which specifiers would work on them?)
I create instances for TimeZoneSeries
and ZoneSeriesTime
.
For now at least, the specifiers are identical to the ones for TimeZone
and ZonedTime
, respectively. Because my instances are rather trivial - they can only create a TimeZoneSeries
with a single TimeZone
that is assumed to work for all eternity both backward and forward in time.
TBH I wasn't really expecting other people to create their own ParseTime or FormatTime instances?
@AshleyYakeley I upgraded the time
library, and got bitten by this today. With an earlier version of the library I had written the following code to change the behaviour of %p
and %P
(to emit midnight
and noon
at 0000 hours and 1200 hours respectively):
newtype FormatTime12 t = FormatTime12 t
timeFormatterHelper :: (FormatTime t, Timeable t) => Char -> Maybe (TimeLocale -> Maybe NumericPadOption -> Maybe Int -> FormatTime12 t -> String)
timeFormatterHelper c = case (Time.formatCharacter c) of
Nothing -> Nothing
Just original ->
let interceptChar tl npo mWidth tm@(FormatTime12 t) = case (t ^. hours, t ^. minutes) of
(0, 0) -> "midnight"
(24, 0) -> "midnight"
(12, 0) -> "noon"
_ -> runOriginal tl npo mWidth tm
runOriginal tl npo mWidth (FormatTime12 t) = original tl npo mWidth t
in if (c=='p' || c=='P')
then Just interceptChar
else Just runOriginal
instance FormatTime (FormatTime12 UTCTime) where
formatCharacter = timeFormatterHelper
instance FormatTime (FormatTime12 LocalTime) where
formatCharacter = timeFormatterHelper
instance FormatTime (FormatTime12 ZonedTime) where
formatCharacter = timeFormatterHelper
instance FormatTime (FormatTime12 TimeOfDay) where
formatCharacter = timeFormatterHelper
With the new version of the library, I cannot figure out how to do this because:
FormatOptions
is not exposed to the outside world- formatting helpers, like
formatString
,formatNumber
,formatNumberStd
, etc are not exposed to the outside world.
What's the recommended way to do something like this in the time
library?
Done.