#!/usr/bin/nawk -f # SccsId[] = "@(#)epoch_time_awk.awk 1.3 08/03/04" #----------------------------------------------------------------------# # epoch_time.awk # # -------------------------------------------------------------------- # # # # Copyright (c) 2006-2008 by Bob Orlando. All rights reserved. # # # # Permission to use, copy, modify and distribute this software # # and its documentation for any purpose and without fee is hereby # # granted, provided that the above copyright notice appear in all # # copies, and that both the copyright notice and this permission # # notice appear in supporting documentation, and that the name of # # Bob Orlando not be used in advertising or publicity pertaining # # to distribution of the software without specific, written prior # # permission. Bob Orlando makes no representations about the # # suitability of this software for any purpose. It is provided # # "as is" without express or implied warranty. # # # # BOB ORLANDO DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS # # SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # # AND FITNESS. IN NO EVENT SHALL BOB ORLANDO BE LIABLE FOR ANY # # SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER # # IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, # # ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF # # THIS SOFTWARE. # # # #----------------------------------------------------------------------# BEGIN \ { #----------------------------# # Process options -h and -z. # #----------------------------# for (n=1; n 0) { yyyy-- cc = int(yyyy / 100) ddddd = yyyy * 365 leapdays = int(yyyy / 4) cc_leapdays = (cc > 0) ? (int(cc / 4)) : 0 ddddd = ddddd + leapdays - cc + cc_leapdays yyyy++ } ddddd += DD #--------------------------------------------------------# # Add the previous month YTD days to our ddddd. If it # # is a leap year, assign julian_leap[] to accum_days[]. # # Then add in YTD days for previous months of this year # #--------------------------------------------------------# if (leap_year(yyyy)) for (i=0; i<13; i++) accum_days[i] = julian_leap[i] else for (i=0; i<13; i++) accum_days[i] = julian_days[i] ddddd += accum_days[MM += 0] # 'MM += 0' removes leading zero return (ddddd) } # function basedate #----------------------------------------------------------------------# function ddddd_to_yyyymmdd(DDDDD, ddddd,yyyy,mmdd,i) # # -------------------------------------------------------------------- # # Globals: julian_days[] and julian_leap[]. # #----------------------------------------------------------------------# { yyyy = ddddd = reduce(DDDDD) sub(/-.*$/,"", yyyy); yyyy += 0 # "+= 0" ensures numeric context sub(/^.*-/,"",ddddd); ddddd += 0 if (leap_year(yyyy)) for (i in julian_leap) julian[i] = julian_leap[i] else for (i in julian_days) julian[i] = julian_days[i] #------------------------------------------------------------# # Reduce ddddd to month and day (we already have the year). # #------------------------------------------------------------# for (i=13; i>0; i--) { if (julian[i] < ddddd) { # if (leap_year(yyyy) && i > 2) ddddd++ ddddd -= julian[i] mmdd = sprintf("%02d%02d", i, ddddd) break } } return (yyyy""mmdd) } # function ddddd_to_yyyymmdd #----------------------------------------------------------------------# function julian_table() #----------------------------------------------------------------------# { split("0 31 59 90 120 151 181 212 243 273 304 334 365", julian_days) split("0 31 60 91 121 152 182 213 244 274 305 335 366", julian_leap) } #----------------------------------------------------------------------# function leap_year(YYYY) # YYYY = year. Returns true|false (1|0). #----------------------------------------------------------------------# { return (((YYYY%4 == 0 && YYYY%100 != 0) || (YYYY%400 == 0)) ? 1 : 0) } # function leap_year #----------------------------------------------------------------------# function reduce(DDDDD, yyyy,ddddd,cc,leapdays,cc_leapdays,i) # #----------------------------------------------------------------------# { for (i=1; ; i++) { yyyy = int(DDDDD / 365) - i ddddd = DDDDD - yyyy * 365 cc = int(yyyy / 100) leapdays = int(yyyy / 4) cc_leapdays = (cc > 0) ? (int(cc / 4)) : 0 leapdays = leapdays - cc + cc_leapdays ddddd -= leapdays yyyy++ if (ddddd > 0) break } return yyyy"-"ddddd } # function reduce #----------------------------------------------------------------------# function secs_since_epoch(ddddd,ddddd_yyyy,sss) #----------------------------------------------------------------------# { #-------------------------------------------------------# # Calling date with "+\%Y\%m\%d" (with escaped percent # # signs) avoids hassles with SCCS and percentYpercent. # #-------------------------------------------------------# if (ARGV[1] == "") "date +\%Y\%m\%d\%H\%M\%S" | getline yyyymmddhhmiss else # yyyymmddhhmiss yyyymmddhhmiss = sprintf("%14s",substr(ARGV[1]"00000000000000",1,14)) yyyy = substr(yyyymmddhhmiss, 1,4) mm = substr(yyyymmddhhmiss, 5,2) dd = substr(yyyymmddhhmiss, 7,2) hh = substr(yyyymmddhhmiss, 9,2) mi = substr(yyyymmddhhmiss,11,2) ss = substr(yyyymmddhhmiss,13,2) ddddd = basedate(yyyy,mm,dd) ddddd_yyyy = basedate(1970,01,01) ddddd -= ddddd_yyyy sss = (ddddd * 86400) + (hh * 3600) + (mi * 60) + ss sss += tz_adj return sss } # function secs_since_epoch #----------------------------------------------------------------------# function shift_ARGV(i,j,k) #----------------------------------------------------------------------# { k = ARGC for (i=1; i<=ARGC; i++) { if (ARGV[i] == "") # If the argument is empty, see is we { # can shift the next one down to it. for (j=i+1; j<=k; j++) { if (ARGV[j] == "") # If the next one is empty, try the one continue # following that. ARGV[i] = ARGV[j] # Once we find an argument, move it down, ARGV[j] = "" # null where it was, decrement arg counter, break # can do this with the next argument. } } } for (i=1; i<=k; i++) # Adjust ARGC if (ARGV[i] == "") # If the argument is empty, ARGC-- # decrement ARGC return ARGC } # function shift_ARGV #----------------------------------------------------------------------# function Usage_and_exit(SPECIFIC_ERROR) #----------------------------------------------------------------------# { if (SPECIFIC_ERROR) print "\n"SPECIFIC_ERROR print "\nPurpose: Return current Unix Epoch time (ssssssssss) or", "\n convert specified Unix Epoch time to yyyymmddhhmiss", "\n datetime, or convert yyyymmddhhmiss datetime to", "\n Unix Epoch seconds.\n", "\n Usage: epoch_time.awk -h -z [-]hh [yyyymmddhhmiss|ssssssssss]", "\n e.g. epoch_time.awk [no options or arguments]", "\n epoch_time.awk 20070121132053", "\n epoch_time.awk 1169385653" exit 1 } #======================================================================# # D O C U M E N T A T I O N # #======================================================================# # # # Author: Bob Orlando (Bob@OrlandoKuntao.com) # # # # Date: May 2, 2006 # # # # Program ID: epoch_time.awk # # # # Purpose: Return current Unix Epoch time (ssssssssss) or # # convert an Epoch seconds argument (seconds since # # January 1, 1970 00:00:00) into yyyymmddhhmiss datetime # # form -- OR -- convert yyyymmddhhmiss datetime argument # # into Unix Epoch seconds. # # # # The script uses the host's time zone, but adjustments # # can be made via the time zone (-z) option. The optarg # # is specified in hours and may be specified negatively. # # # # Usage: [gn]awk -f epoch_time.awk -- -h -z [-]hh \ # # [yyyymmddhhmiss|ssssssssss] # # # # -- = This option must come first for it # # tells Awk to pass on all options # # that follow to the script itself. # # -h = Help (usage brief) # # -z [-]hh = Timezone adjustment in hours # # yyyymmddhhmiss = Converts to epoch seconds # # ssssssssss = Converts to yyyymmddhhmiss datetime # # # # Examples: 1. epoch_time.awk # No options or argument # # 2. epoch_time.awk 1164718505 # # 3. epoch_time.awk 20061128125505 # # 4. epoch_time.awk -- -z 2 1164718505 # # 5. epoch_time.awk -- -z 2 20061128125505 # # 6. epoch_time.awk -- -z -2 1164718505 # # # # Displays: 1. 1164718505 # Current datetime to Epoch seconds # # 2. 20061128125505 # Epoch seconds to yyyymmddhhmiss # # 3. 1164718505 # yyyymmddhhmiss to epoch seconds # # 4. 20061128145505 # Adjusted by 2 hour timezone # # 5. 1164725705 # Adjusted by 2 hours # # 6. 20061128105505 # Adjusted by -2 hours # # # # Modified: 2008-03-04 Bob Orlando # # v1.3 * Bug fix: Thanks to Mahir Aydin for # # pointing this out and identifying the fix. # # The following line was commented out from # # ddddd_to_yyyymmdd function: # # # # if (leap_year(yyyy) && i > 2) ddddd++ # # # # The line was "adding one day if the year # # is a leap year and the month is after # # February, which is unnecessary, since you # # already have two separate tables for leap # # years and normal years, and [you] use the # # correct one." # # # # 2007-04-25 Bob Orlando # # v1.2 * Bug fix: Timezone option (-z). Changed # # if (tz_adj !~ /^[0-9]+$/) # # to # # if (ARGV[2] !~ /^-?[0-9]+$/) # # # # 2006-05-02 Bob Orlando # # v1.1 * Initial release. # # # #----------------------------------------------------------------------#