nth date


 
Thread Tools Search this Thread
Top Forums UNIX for Advanced & Expert Users nth date
# 1  
Old 09-21-2012
nth date

Hi
I need to get the date of 50th day from the last friday for one of the calculation into variable in Unix script. The format required is YYYYMMDD. I have solaris OS and dont have GNU date. I would appreciate if some one can help me with this.
It can be a onliner or function or block of code.

Thanks
# 2  
Old 09-21-2012
I wrote this ultimate time tool for all those shell scripts wanting to do time stuff - parsing, clock, offsets and formatted output. Complex questions might mean you call it more than once or in a loop, like what is the day of month of the next third thursday:
Code:
$ cat mysrc/tm2tm.c
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <time.h>
#include <errno.h>
#include <ctype.h>
static void usage_exit()
{
        fputs(
"\n"
"Usage: tm2tm { -c | { - | <tm_str> } <in_fmt> } <delta> <out_fmt>\n"
" First, gets dates and time(s):\n"
"  - when '-c' is used, from gettimeofday() (microsecond system clock)\n"
"  - when '-' is used, from the front of each line of stdin per <in_fmt>\n"
"  - else, from the front of <tm_str> per <in_fmt>\n"
" The default year is 2000, and for other elements, minimum values.\n"
" The <in_fmt> is either one of these or composed per strptime():\n"
"    %s       Absolute Unix time in integer seconds\n"
"    %s.%F    Unix time in integer and fractional 6 place seconds\n"
"    %s.%f    Unix time in integer and fractional 1-6 place seconds\n"
" Modify each time by <delta>, an optionally sign, integer number,\n"
"  and optional suffix indicating the time unit (default seconds):\n"
"    Y or y   years           m        months\n"
"    D or d   days            H or h   hours\n"
"    M        minutes         S or s   seconds\n"
" Format the time by <out_fmt>, which supports all of the strftime() values,\n"
"  plus the following:\n"
"    %s       Absolute Unix time in seconds\n"
"    %F       Fractional 6 place seconds\n"
"    %f       Fractional 1-6 place, zero suppressed seconds\n"
" Write the converted time plus any following input data to standard out.\n"
" For example: tm2tm '5/7/05 15:34' '%m/%d/%y %H:%M' -8h '%Y-%m-%d %r %Z'\n"
"  prints '2005-05-07 07:34:00 AM EDT'\n",
                stderr );
        exit( 1 );
}
static void add_u_time( char *os, char *is, struct timeval *tv )
{
        int st ;
        int i ;
        for ( st=0 ; *is ; os++, is++ )
        {
                switch ( *os = *is )
                {
                case '%':
                        st ^= 1 ;
                        continue ;
                case 's':
                        if ( st )
                        {
                                st = 0 ;
                                os += sprintf( os - 1, "%u", tv->tv_sec ) ;
                                os -= 2 ;
                        }
                        continue ;
                case 'f':
                case 'F':
                        if ( st )
                        {
                                st = 0 ;
                                os += sprintf( os - 1, "%6.6u", tv->tv_usec );
                                os -= 2 ;
                                /* trim off up to 5 trailing 0's for %f */
                                for ( i = 0 ;
                                      i < 5 && *os == '0' && *is == 'f' ;
                                      i++ )
                                {
                                        os-- ;
                                }
                        }
                        continue ;
                default:
                        st = 0 ;
                }
        }
        *os = NULL ;
}
int main( int argc, char **argv )
{
        long td = 0L ;
        struct tm tm ;
        struct timeval tv = { 0, 0 };
        int c = 0 ;
        int sff = 0 ;
        int dst_sav ;
        char *td_sufx ;
        char *in_sufx ;
        char *tbufp ;
        char *cp ;
        char tbuf[65536];
        char tbuf2[65536];
        char tbuf3[65536];
        if ( argc < 4 )
                usage_exit();
        if ( !strcmp( argv[1], "-c" ) )
        {
                if ( argc != 4 )
                {
                        usage_exit();
                }
                c = 1 ;
                in_sufx = "" ;
                tbufp = "<system_clock>" ;
        }
        else
        {
                if ( argc != 5 )
                {
                        usage_exit();
                }
                if ( !strcmp( argv[1], "-" ) )
                {
                        tbufp = tbuf ;
                }
                else
                {
                        tbufp = argv[1];
                }
                if ( !strcmp( argv[2], "%s" ) )
                {
                        sff = 1 ;
                }
                else if ( !strcmp( argv[2], "%s.%F" ) )
                {
                        sff = 2 ;
                }
                else if ( !strcmp( argv[2], "%s.%f" ) )
                {
                        sff = 3 ;
                }
        }
        td = strtol( argv[ 3 - c ], &td_sufx, 0 );
        while ( *td_sufx
             && isspace( *td_sufx ) )
        {
                td_sufx++ ;
        }
        do
        {
                if ( c )
                {
                        if ( gettimeofday( &tv, (void *)NULL ) )
                        {
                                perror( "gettimeofday()" );
                                exit( 1 );
                        }
                        localtime_r( &tv.tv_sec, &tm );
                }
                else
                {
                        if ( tbufp == tbuf )
                        {
                                if ( !fgets( tbuf, sizeof( tbuf ), stdin ) )
                                {
                                        if ( ferror( stdin ) )
                                        {
                                                perror( "stdin" );
                                                exit( 1 );
                                        }
                                        exit( 0 );
                                }
                        }
                        if ( sff )
                        {
                                errno = 0 ;
                                tv.tv_sec = strtoul( tbufp, &in_sufx, 0 );
                                if ( errno )
                                {
                                        fprintf( stderr,
                                            "\nInput '%s' not format '%s'",
                                                tbufp, argv[2] );
                                        perror( "" );
                                        continue ;
                                }
                                localtime_r( &tv.tv_sec, &tm );
                                if ( sff > 1 )
                                {
                                        cp = in_sufx ;
                                        errno = 0 ;
                                        tv.tv_usec = strtoul( cp, &in_sufx, 0 );
                                        if ( errno
                                          || *in_sufx != '.' )
                                        {
                                                fprintf( stderr,
                                                 "\nInput '%s' not format '%s'",
                                                        tbufp, argv[2] );
                                                perror( "" );
                                                continue ;
                                        }
                                        while ( ( in_sufx - cp ) < 6
                                             && sff > 2 )
                                        {
                                                tv.tv_usec *= 10 ;
                                                cp-- ;
                                        }
                                }
                        }
                        else
                        {
                                if ( !( in_sufx = strptime( tbufp,
                                                        argv[2], &tm ) ) )
                                {
                                        fprintf( stderr,
                                                "\nInput '%s' not format '%s'",
                                                tbufp, argv[2] );
                                        continue ;
                                }
                                if ( tm.tm_year < 69 )
                                {
                                        tm.tm_year += 100 ;
                                }
                                if ( !tm.tm_mday )
                                {
                                        tm.tm_mday = 1 ;
                                }
                                dst_sav = tm.tm_isdst ;
                                errno = 0 ;
                                tv.tv_sec = mktime( &tm );
                                if ( errno )
                                {
                                        fprintf( stderr, "\n"
"Error converting date-time '%s' using format '%s': ",
                                                tbufp, argv[ 2 ] );
                                        perror( "" );
                                        continue ;
                                }
                                if ( dst_sav < tm.tm_isdst )
                                {
                                        tm.tm_hour-- ;
                                        tv.tv_sec = mktime( &tm );
                                }
                        }
                }
                if ( td )
                {
                        switch( *td_sufx )
                        {
                        case 'y':
                        case 'Y':
                                tm.tm_year += td ;
                                break ;
                        case 'm':
                                tm.tm_mon += td ;
                                break ;
                        case 'w':
                        case 'W':
                                tm.tm_mday += ( 7 * td );
                                break ;
                        case 'd':
                        case 'D':
                                tm.tm_mday += td ;
                                break ;
                        case 'h':
                        case 'H':
                                tm.tm_hour += td ;
                                break ;
                        case 'M':
                                tm.tm_min += td ;
                                break ;
                        case 's':
                        case 'S':
                        case NULL:
                                tm.tm_sec += td ;
                                break ;
                        default:
                                fprintf( stderr,
        "\n"
        "Fatal: Unknown delta unit %c in delta arg '%s'.\n",
                                        *td_sufx, argv[ 3 - c ] );
                                exit( 1 );
                        }
                        errno = 0 ;
                        tv.tv_sec = mktime( &tm );
                        if ( errno )
                        {
                                fprintf( stderr, "\n"
        "Error converting time + delta '%s' using ",
                                        argv[ 3 - c ] );
                                perror( "mktime()" );
                                continue ;
                        }
                } /* if td */
                add_u_time( tbuf2, argv[ 4 - c ], &tv );
                if ( !strftime( tbuf3, sizeof( tbuf3 ), tbuf2, &tm ) )
                {
                        fprintf( stderr, "\n"
"String too long using format '%s' on time '%s'\n", tbuf2, tbufp );
                        continue ;
                }
                if ( 0 > printf( "%s%s%s", tbuf3, in_sufx,
                                        ( tbufp != tbuf ? "\n" : "" ) ) )
                {
                        if ( ferror( stdout ) )
                        {
                                perror( "stdout" );
                                exit( 1 );
                        }
                        exit( 0 );
                }
        } while ( tbufp == tbuf ) ;
        exit( 0 );
}

The input option for time at the front of a line fits many files, and I have another tool mystat that is a wrapper for the stat() call that can stream file names in (if not on the command line) and by default outputs (file mod times in decimal unix time TAB file name), so you can sort -n to find the oldest or newest of any number of files.

Last edited by DGPickett; 09-21-2012 at 03:13 PM..
This User Gave Thanks to DGPickett For This Post:
# 3  
Old 09-21-2012
try this: note it uses ksh - if you use bash uncomment the red code; comment the blue code and change the shebang to /bin/bash
Code:
#!/bin/ksh
#
# assumptions - the LAST friday means:
#       Find a Friday (not today, even if today is Friday) 
#         in the past
# number of days friday is in the past

set -A weekdays_dec 2 3 4 5 6 7 1
# in bash this is           
# declare -a weekdays_dec=( 2 3 4 5 6 7 1 )

decrement=${weekdays_dec[`date +%w`]}
# 86400 secs per day * decrement
decrement=$(( $decrement * 86400 ))

# 86400 secs per day * 50
fifty_days=$(( 86400 * 50 ))

when=`perl -e 'print time;'`
when=$(( $when - $fifty_days )) 

when=$(( $when - $decrement ))
answer=`perl -e 'use POSIX qw(strftime);
              $mt = strftime "%Y%m%d", localtime($ARGV[0]);
              print $mt;' $when`
echo $answer


Last edited by jim mcnamara; 09-21-2012 at 02:05 PM.. Reason: change code to meet specs.
This User Gave Thanks to jim mcnamara For This Post:
# 4  
Old 09-21-2012
Thanks Jim.
I need 50 days OLD/ BACK date from the last Friday.
I am trying to tweek the code. Let me know if you can.

Thanks for the help
# 5  
Old 09-21-2012
You specifications are not clear to me.
Please give me sample input (some date) and then sample output.
# 6  
Old 09-21-2012
Hi Jim
I need to get 50 days back date from last friday i.e 9/14/2012
The output should be 20120725
# 7  
Old 09-21-2012
Code:
when=$(( $when + $fifty_days )) 
# change to
when=$(( $when - $fifty_days ))

That is a minus sign.

Also changed the original post to reflect the change.
This User Gave Thanks to jim mcnamara For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Date: invalid date trying to set Linux date in specific format

i try to set linux date & time in specific format but it keep giving me error Example : date "+%d-%m-%C%y %H:%M:%S" -d "19-01-2017 00:05:01" or date +"%d-%m-%C%y %H:%M:%S" -d "19-01-2017 00:05:01" keep giving me this error : date: invalid date ‘19-01-2017 00:05:01' Please use CODE tags... (7 Replies)
Discussion started by: umen
7 Replies

2. UNIX for Advanced & Expert Users

Help changing date format in the nth field

Hi, I have two (2) things that I want to do. First is to change the date format that is in the nth field from MM/DD/YY to YY/MM/DD. Preferably, I wish I know how to make it a 4-digit year but I don't. Problem is I can only assume it is a 20 century Second is somehow know how to figure out... (1 Reply)
Discussion started by: newbie_01
1 Replies

3. Shell Programming and Scripting

Replace nth to nth character?

Hi I got the following problem and I wonder if some could please help me out? I'd like to replace character 8 - 16 , 16 - 24 cat file ... (2 Replies)
Discussion started by: stinkefisch
2 Replies

4. Shell Programming and Scripting

Replace a value of Nth field of nth row

Using Awk, how can I achieve the following? I have set of record numbers, for which, I have to replace the nth field with some values, say spaces. Eg: Set of Records : 4,9,10,55,89,etc I have to change the 8th field of all the above set of records to spaces (10 spaces). Its a delimited... (1 Reply)
Discussion started by: deepakwins
1 Replies

5. UNIX for Dummies Questions & Answers

Print Nth to last field

Hey, I'm sure this is answered somewhere but my Googling has turned up nothing. I have a file with data in the following format: <desription of event> at <time and date>The desription of the event is variable length and hence when the list is displayed it is hard to easily see the date (and... (8 Replies)
Discussion started by: RECrerar
8 Replies

6. Shell Programming and Scripting

Replace the nth column date as MM/DD/YYYY

Hi, I need some unix command to replace the following thing. cat test.dat 1234|test|8/19/2009|8/20/2009|test 1234|test|8/9/2009|8/21/2009|test 1234|test|8/1/2009|8/2/2009|test after processing 1234|test|08/19/2009|08/20/2009|test 1234|test|08/09/2009|08/21/2009|test... (6 Replies)
Discussion started by: anshaa
6 Replies

7. Shell Programming and Scripting

Converting a date to friday date and finding Min/Max date

Dear all, I have 2 questions. I have a file with many rows which has date of the format YYYYMMDD. 1. I need to change the date to that weeks friday date(Ex: 20120716(monday) to 20120720). Satuday/Sunday has to be changed to next week friday date too. 2. After converting the date to... (10 Replies)
Discussion started by: 2001.arun
10 Replies

8. Shell Programming and Scripting

Calculating average for every Nth line in the Nth column

Is there an awk script that can easily perform the following operation? I have a data file that is in the format of 1944-12,5.6 1945-01,9.8 1945-02,6.7 1945-03,9.3 1945-04,5.9 1945-05,0.7 1945-06,0.0 1945-07,0.0 1945-08,0.0 1945-09,0.0 1945-10,0.2 1945-11,10.5 1945-12,22.3... (3 Replies)
Discussion started by: ncwxpanther
3 Replies

9. Shell Programming and Scripting

Using AWK to find top Nth values in Nth column

I have an awk script to find the maximum value of the 2nd column of a 2 column datafile, but I need to find the top 5 maximum values of the 2nd column. Here is the script that works for the maximum value. awk 'BEGIN { subjectmax=$1 ; max=0} $2 >= max {subjectmax=$1 ; max=$2} END {print... (3 Replies)
Discussion started by: ncwxpanther
3 Replies

10. Shell Programming and Scripting

Date One Week Ago From Given Date, Not From Current Date

Hi all, I've used various scripts in the past to work out the date last week from the current date, however I now have a need to work out the date 1 week from a given date. So for example, if I have a date of the 23rd July 2010, I would like a script that can work out that one week back was... (4 Replies)
Discussion started by: Donkey25
4 Replies
Login or Register to Ask a Question