strptime 0.1.6 → 0.1.7
raw patch · 3 files changed
+120/−7 lines, 3 files
Files
- Data/Time/Parse.hsc +4/−2
- cbits/hstrptime.c +115/−4
- strptime.cabal +1/−1
Data/Time/Parse.hsc view
@@ -38,7 +38,8 @@ -- | Given a format string in the format of strptime (see <http://linux.die.net/man/3/strptime>) -- and a data string, parse a date+time value from the data string and also return the remainder -- of the data string. We also support a "%OS" format specifier for fractional seconds, because- -- we are using the strptime from r-project.org.+ -- we are using the strptime from r-project.org. We also support "%^[+-][N]s" for multiples of + -- seconds since epoch, for example "%^-3s" is milliseconds since epoch (N can only be 1 digit) strptime :: a -> a -> Maybe (LocalTime, a) instance Strptime [Char] where@@ -80,6 +81,7 @@ return $ \s -> unsafePerformIO $ S.useAsCString s $ \cs -> do allocaBytes (#const sizeof(struct tm)) $ \p_tm -> do alloca $ \p_fsecs -> do+ poke p_fsecs 0 alloca $ \p_offset -> do last <- hstrptime_c cs (castPtr ztf) p_tm p_fsecs p_offset if last == nullPtr@@ -93,7 +95,7 @@ year <- (#peek struct tm,tm_year ) p_tm :: IO CInt fsecs <- peek p_fsecs let day = fromGregorian (fromIntegral (year+1900)) (1+fromIntegral month) (fromIntegral mday)- let tod = TimeOfDay (fromIntegral hour) (fromIntegral min) (fromIntegral (round (fsecs*1000000)) / fromIntegral 1000000)+ let tod = TimeOfDay (fromIntegral hour) (fromIntegral min) (fromIntegral (sec*1000000 + round (fsecs*1000000)) / fromIntegral 1000000) touchForeignPtr fztf
cbits/hstrptime.c view
@@ -391,6 +391,7 @@ character for character and construct the result while doing this. */ time_t secs = 0;+ struct tm *tm2; if (*rp < L'0' || *rp > L'9') /* We need at least one digit. */ return NULL;@@ -402,11 +403,66 @@ } while (*rp >= L'0' && *rp <= L'9'); - if ((tm = localtime (&secs)) == NULL)+ if ((tm2 = localtime (&secs)) == NULL) /* Error in function. */ return NULL;+ *tm = *tm2; } break;+ /* for example, %^-3s - milliseconds, %^+3s - thousands of seconds */+ case L'^':+ {+ wchar_t sign = *fmt++;+ int power = *fmt++ - L'0';+ int tenpower = 1;+ double fsec = 0;++ /* The number of seconds may be very high so we cannot use+ the `get_number' macro. Instead read the number+ character for character and construct the result while+ doing this. */+ time_t secs = 0;+ struct tm *tm2;+ if (sign != L'-' && sign != L'+')+ return NULL;++ if (power < 0 || power > 9)+ return NULL;++ if (*fmt++ != L's')+ return NULL;++ if (*rp < L'0' || *rp > L'9')+ /* We need at least one digit. */+ return NULL;++ do+ {+ secs *= 10;+ secs += *rp++ - L'0';+ }+ while (*rp >= L'0' && *rp <= L'9');+ + while (power-- > 0)+ tenpower *= 10; + if(sign == '-')+ {+ fsec = secs % tenpower;+ secs /= tenpower;+ fsec /= tenpower;+ *psecs = fsec;+ }+ else+ {+ secs *= tenpower;+ }++ if ((tm2 = localtime (&secs)) == NULL)+ /* Error in function. */+ return NULL;+ *tm = *tm2;+ }+ break; case L'S': get_number (0, 61, 2); tm->tm_sec = val;@@ -547,8 +603,6 @@ tm->tm_min = val; break; case L'S':- /* Match seconds using alternate numeric symbols.- get_alt_number (0, 61, 2); */ { double sval; wchar_t *end;@@ -854,6 +908,7 @@ character for character and construct the result while doing this. */ time_t secs = 0;+ struct tm *tm2; if (*rp < '0' || *rp > '9') /* We need at least one digit. */ return NULL;@@ -865,9 +920,65 @@ } while (*rp >= '0' && *rp <= '9'); - if ((tm = localtime (&secs)) == NULL)+ if ((tm2 = localtime (&secs)) == NULL) /* Error in function. */ return NULL;+ *tm = *tm2;+ }+ break;+ /* for example, %^-3s - milliseconds, %^+3s - thousands of seconds */+ case '^':+ {+ char sign = *fmt++;+ int power = *fmt++ - '0';+ int tenpower = 1;+ double fsec = 0;++ /* The number of seconds may be very high so we cannot use+ the `get_number' macro. Instead read the number+ character for character and construct the result while+ doing this. */+ time_t secs = 0;+ struct tm *tm2;+ if (sign != '-' && sign != '+')+ return NULL;++ if (power < 0 || power > 9)+ return NULL;++ if (*fmt++ != 's')+ return NULL;++ if (*rp < '0' || *rp > '9')+ /* We need at least one digit. */+ return NULL;++ do+ {+ secs *= 10;+ secs += *rp++ - '0';+ }+ while (*rp >= '0' && *rp <= '9');+ + while (power-- > 0)+ tenpower *= 10; + if(sign == '-')+ {+ fsec = secs % tenpower;+ secs /= tenpower;+ fsec /= tenpower;+ *psecs = fsec;+ }+ else+ {+ secs *= tenpower;+ }+++ if ((tm2 = localtime (&secs)) == NULL)+ /* Error in function. */+ return NULL;+ *tm = *tm2; } break; case 'S':
strptime.cabal view
@@ -1,6 +1,6 @@ Name: strptime Category: System, Data, Parsing-Version: 0.1.6+Version: 0.1.7 Cabal-version: >= 1.2 Build-type: Simple Copyright: Eugene Kirpichov