how to get day of the year in shell? - linux

How can I get the day of the year in shell?
date '+%V' will give me the week of the year, which is 15 for today; but I need to find the day of the year!

From the coreutils date manual:
%j day of year (001..366)

Use the date command and the %j option...
doy=$(date +%j)

POSIX mandates the format string %j for getting the day of the year, so if you want it for today's date, you are done, and have a portable solution.
date +%j
For getting the day number of an arbitrary date, the situation is somewhat more complex.
On Linux, you will usually have GNU date, which lets you query for an arbitrary date with the -d option.
date -d '1970-04-01' +%j
The argument to -d can be a fairly free-form expression, including relative times like "3 weeks ago".
date -d "3 weeks ago" +%j
On BSD-like platforms, including MacOS, the mechanism for specifying a date to format is different. You can ask it to format a date with -j and specify the date as an argument (not an option), and optionally specify how the string argument should be parsed with -f.
date -j 04010000 +%j
displays the day number for April 1st 00:00.
The string argument to specify which date to examine is rather weird, and requires the minutes to be specified, and then optionally allows you to prefix with ((month,) day, and) hour, and optionally allows year as a suffix (sic).
date -j -f "%Y-%m-%d" 1970-04-01 +%j
uses -f format date to pass in a date in a more standard format, and prints the day number of that.
There's also the -v option which allows you to specify relative times.
date -j -v -3w +%j
displays the day number of the date three weeks ago.
If you are looking for a proper POSIX-portable solution for getting the day number of arbitrary dates, the least unattractive solution might be to create your own program. If you can rely on Python or Perl (or GNU Awk) to be installed, those make it relatively easy, though it's still a bit of a chore using only their default libraries.

Related

How to convert a bash string to date format? [duplicate]

This question already has answers here:
How to convert YYYYMMDDHHMMSS to a date readable by `date`
(6 answers)
Closed 10 months ago.
I have a bash string 20220416124334 (the string is not epoch) and I want to convert it to date format so it should look like this: 2022/04/16 12:43:34
I've tried:
[manjaro#manjaro ~]$ date -d '20220416124334' "+%Y/%m/%d %H:%M:%S"
date: invalid date ‘20220416124334’
How should I do it correctly ?
I would expect to use the date command, as you employ it, with a number that represents the number of seconds since the epoch. It seems your number is a formatted date yyyymmddhhmiss.
If you don't need to validate the string that represents a formatted date, then you can use sed to insert extra formatting characters:
echo '20220416124334' | sed -E 's/(....)(..)(..)(..)(..)(..)/\1\/\2\/\3 \4:\5:\6/'
If you end up taking as input a number of seconds since the epoch, then do it this way, keeping in mind that a number means different times in different time zones at different times of the year (eyeroll):
date -u -r 1650113014 "+%Y/%m/%d %H:%M:%S"

How can I display Unix day (not seconds) in date formatting?

The date is approaching (in fact, 2022-01-08), when Unix time turns 19000-days old. Currently, there is a way (namely, %s) to display Unix second in dates, but there seem to be no way to display Unix day in date formatting. How does one display Unix day in dates? If not possible, then how to introduce new date formatting symbol (%?) symbol for it?
Why?
Epoch date is easy to compute just dividing Unix seconds / 86400, and works well as natural decimal time, where:
1 dYear = 1000 days, 1 dMonth = 100 days, 1 dWeek = 10 days,
1 dHour = 0.1 days, 1 dMinute = 0.001 days, 1 dSecond = 0.00001 days.
Unix day digits, unlike Unix second's digits, approximate lengths of ordinary concepts of time with less than 1 order of magnitude, thus work well as decimal time and date, where:
For example, now is Unix day = 18993.94830052069 means:
18993.94830052069
\ \\\ \ \ 30.052069 th decimal second
\ \\\ \ 48 th decimal minute
\ \\\ 9 th decimal hour
\ \\ 3 rd day of week
\ \ 9 th decimal week
\ 9 th decimal month
18 th decimal year
Unix day, interpreted this way, has the benefit of convenience of use as natural support for decimal time, so some people use it and need it.
Ultimately, I'd like to know a path for incorporating this display of time as one of the supported ways of displaying date and time in *nix systems.
date +%s displays the Unix second, is there a way to display Unix day with it?
No, it is not possible.
how to introduce new date formatting symbol (%?) symbol for it?
Download the sources of the date utility implementation that you are using and patch it with a custom modifier. GNU date (if you are using GNU date...) is part of GNU coretuils, see https://www.gnu.org/software/coreutils/ . Date utility follows POSIX specification.
I do not have ever encountered any need for a "number of days since epoch with fractional part" format. I do not believe it has any practical usage. I do not believe such a formatting specifier should be added to date. I see no value in it over "number of seconds since epoch with fractional part" (date +%s.%N), it's just a change of unit. I wouldn't want those hard-working GNU developers that are giving their work to the world for free, for them to spend time on something that has no practical application. I would like them to they spent their time with their families or on other more important things. As such, I encourage you to not take developers time, unless you can strongly prove that the community requires such a formatting specifier for practical reasons.

Sum number of days to specific date in dd/mm/yyyy format in bash

This might be a simple problem but I'm having some trouble getting trough it:
I need to sum a number of weeks to a specific date that is in the format dd/mm/yyyy.
I know I can sum number of weeks to the current day using date -d "+1 week" +"%d%m%Y", but I'm having trouble when I try to do this to a specific date in the format I mentioned above (29/06/2019, for example).
Would anyone be able to explain how I can perform this operation?
$ date -d '20190629+1 week' +"%d%m%Y"
06072019
$ date -d '06/29/2019+1 week' +"%d%m%Y"
06072019
without delimiters it's not a valid date format though.

Calendar months variables in BASH script

I am writing a BASH script that calls an API that presents metrics for specific time-frames. I plan to run the script on a cron job on the 1st of each month, the API call needs to contain the start and end time and be in a epoch format with milliseconds. Milliseconds should be ok to set to 000 as it doesnt need to be that specific but the API requires it.
How can I code the script to look at the current human readable time then look at the exact same time exactly 1 calendar month before, then convert both outputs to epoch, and then enter the epoch times in the curl command as a variable?
Example:
Script runs at 1am on July 1st, script then understands a full calendar month before was June 1st, converts both to epoch, places them into the curl command using variables.
I understand how to get a human readable date for 1 month ago, however I am unsure how best to convert these dates to epoch.
date --date="1 month ago" +"%d%m%Y"
To create a variable using date in epoch times with milliseconds:
ENDDATE=`date +%s%N | cut -b1-13`
STARTDATE=`date --date="1 month ago" +%s%N | cut -b1-13`
Use these variables in the cURL command.

Get Monday and Sunday etc.. for a week for any date as parameter in Unix

How to get the date of Monday and Sunday in a week for a date?
This gives date for 'last' monday:
date -dlast-monday +%Y%m%d
I want to pass a date as parameter to find the Monday and Sunday for that week. Basically, I want to get Sunday and Monday for a week, for ANY date, NOT only for last monday.
Try this:
export day=2013-10-01
date -d "$day -$(date -d $day +%w) days"
This will always print the Sunday before the given date (or the date itself).
date -d "$day -$(date -d $day +%u) days"
This will always print the Sunday before the given date (and never the date itself).
For Mondays you need to add + 1 day:
date -d "$day -$(date -d $day +%u) days + 1 day"
You should also consider what Monday or Sunday you want to get (this wasn't quite clear) for which date. This also depends on whether you consider the Sunday the first or the last day of the week.
date can parse the date on the command line like so:
date -j -f %s 1380628152
which is the date+time in seconds since the UNIX epoch. You can combine the command abovewith your command. The -j means you don't want to actually set the date. The -f specifies a strftime string to use to parse the date on the command line.
Please note that this is on a BSD system and it looks like you are on a GNU system with different options to date (but it must support something similar).

Resources