DEV Community

Myoungjin Jeon
Myoungjin Jeon

Posted on • Edited on

[Short Prog] Week Number Getter

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();
}
Enter fullscreen mode Exit fullscreen mode
> chmod u+x week-number.raku
> week-number.raku 2021 8 4
31
Enter fullscreen mode Exit fullscreen mode

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();
}
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>" ] )
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
> stack build
> stack install
> week-number-exe 2021 8 4
31
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)