Myoungjin Jeon
Posted on August 5, 2021
The one way to store my weekly documents in a directory or a weekly task in a spreadsheet is to store them into a separate directory (or a sheet) by weekly basis. and I used the week number because it has shorter name than using period notation like (08.02-08.08).
I scanned some invoices and name it in sort of "20210805.Chicken.pdf" then I move them into appropriate "week -number-ed" directory.
then I realised that there might be some automatic way to put them into matched weekly directory.
How to get week number in Raku
I'm a raku user. and I could make it a simple terminal interface programme like below.
#!/usr/bin/env raku
multi sub MAIN ( Int $year, Int $month, Int $day ) {
say Date.new( :$year, :$month, :$day ).week-number();
}
> chmod u+x week-number.raku
> week-number.raku 2021 8 4
31
I think it's pretty straight forward if get used to some syntax.
If you want to use a single text like "20210804"
I could add one more multi sub for the MAIN()
sub cut-off-last-two-digits( @i ) returns Int {
# warning: side effect
( @i.pop, @i.pop ).reverse.join.Int
}
multi sub MAIN ( Int \yyyymmdd ) {
my @i = yyyymmdd.comb;
my ( $year, $month, $day );
$day = cut-off-last-two-digits @i;
$month = cut-off-last-two-digits @i;
$year = @i.join.Int;
if (( $year, $month, $day )>>.defined).any == False {
die "check your input: {yyyymmdd}";
}
samewith( $year, $month, $day );
}
multi sub MAIN ( Int $year, Int $month, Int $day ) {
say Date.new( :$year, :$month, :$day ).week-number();
}
Perl5 Version
I searched the internet and I used DateTime module to implement.
but I guess DateTime is quite heavy module. because perl is normally very very fast but this programme isn't.
#!/usr/bin/env perl
use strict; use warnings;
use v5.26;
use DateTime;
use File::Basename;
our $PROG = $0;
my @parsed;
my ( $year, $month, $day );
use enum qw(F_YEAR F_MONTH F_DAY);
sub usage {
print << 'END_OF_USAGE';
$PROG <YYYYMMDD>
OR
$PROG <YYYY> <MM> <DD>
END_OF_USAGE
}
if ( @ARGV == 1 ) {
# parse as YYYYMMDD
my $str = $ARGV[0];
@parsed = $str =~ /^(\d+)(\d\d)(\d\d)$/;
} elsif ( @ARGV == 3 ) {
@parsed = @ARGV;
} else {
usage();
exit 1;
}
( $year, $month, $day ) = @parsed[F_YEAR, F_MONTH, F_DAY];
my $dt = DateTime->new( year => $year,
month => $month,
day => $day );
print $dt->week_number();
Haskell Version
I still hate some part of code and there is no proper way to handle errors but it is working fast. so I'm going to stick with this programme for a while.
> stack new week-number
app/Main.hs
module Main where
import System.Environment
import Lib
main :: IO ()
main = do
args <- getArgs -- note: args :: [String]
putStrLn (case args of
yyyymmdd:[] ->
weekNumberStringFromString yyyymmdd
y:m:d:[] ->
let y' = (read y :: Integer)
m' = (read m :: Int)
d' = (read d :: Int)
in
weekNumberStringFromGregorian y' m' d'
_ ->
unlines
[ "usage:"
, "week-number: <yyyymmdd>"
, " or"
, "week-number: <yyyy> <m> <d>" ] )
src/Lib.hs
module Lib
( weekNumberStringFromString
, weekNumberStringFromGregorian
) where
import qualified Data.Time as DT
weekNumberStringFromString :: String -> String
weekNumberStringFromString yyyymmdd =
let ut = DT.parseTimeOrError
True DT.defaultTimeLocale "%Y%m%d" yyyymmdd :: DT.UTCTime
in
DT.formatTime DT.defaultTimeLocale "%V" ut
weekNumberStringFromGregorian :: Integer -> Int -> Int -> String
weekNumberStringFromGregorian y m d =
( DT.formatTime DT.defaultTimeLocale "%V" ) $ DT.fromGregorian y m d
> stack build
> stack install
> week-number-exe 2021 8 4
31
so now I need to make some script go through the file
and get the date information from the file name and move them into
right place.
Okay. That's all today.
Posted on August 5, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.