Skip to content

Instantly share code, notes, and snippets.

@0racle
Created June 18, 2021 03:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0racle/67c4e9e8f516f565b9d5911ac2162f3c to your computer and use it in GitHub Desktop.
Save 0racle/67c4e9e8f516f565b9d5911ac2162f3c to your computer and use it in GitHub Desktop.
Raku Native strftime/strptime

I'm no NativeCall expert... maybe there's a better way to allocate enough mem other than buf8.allocate(MAX);.

Suggestions welcome

use lib 'lib';
use DateTime::Strings;
my $dt = parse-time('27/02/2015 10:32:04', '%d/%m/%Y %H:%M:%S');
say $dt.^name;
# DateTime
say $dt;
# 2015-02-27T10:32:04Z
say format-time($dt, '%d/%m/%Y %H:%M:%S');
# 27/02/2015 10:32:04
my $now = DateTime.now;
say $now;
say format-time($now, '%c');
unit module DateTime::Strings;
use NativeCall;
constant MAX = 256;
my class tm is repr('CStruct') {
has int32 $.second;
has int32 $.minute;
has int32 $.hour;
has int32 $.day;
has int32 $.month;
has int32 $.year;
has int32 $.wday;
has int32 $.yday;
has int32 $.isdst;
multi method new(DateTime $DT) {
given $DT {
self.bless(
second => .whole-second,
minute => .minute,
hour => .hour,
day => .day-of-month,
month => .month - 1,
year => .year - 1900,
wday => .day-of-week,
yday => .day-of-year,
isdst => 0,
);
}
}
}
sub strptime(Str, Str, tm --> Str) is native { * }
sub strftime(Blob, size_t, Str, tm --> size_t) is native { * }
sub parse-time (Str $string, Str $format) is export {
my tm $tm .= new;
strptime($string, $format, $tm) orelse {
fail("Failed to parse '$string' with format -- '$format'")
}
my $year = $tm.year ?? $tm.year + 1900 !! DateTime.now.year;
DateTime.new(
year => $year,
month => ($tm.month + 1 || 1),
day => ($tm.day || 1),
hour => $tm.hour,
minute => $tm.minute,
second => $tm.second,
);
}
sub format-time (DateTime $DT, Str $format) is export {
my tm $tm .= new($DT);
my $result := buf8.allocate(MAX);
strftime($result, MAX, $format, $tm);
$result.decode;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment