Get first date of current month in MacOS terminal - macos

uisng the command echo $(date "+%F" -d "$(date +'%Y-%m-01') 0 month") i can get the first date of that month. but the same is not working on mac terminal. What needs to be changed?
echo $(date "+%F" -d "$(date +'%Y-%m-01') 0 month")
date: illegal time format
usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
[-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]

The date libraries in *BSD and GNU systems are different and the options supported vary between them. The -d flag which supports a myriad of functions in GNU date is replaced by the -f option in BSD (See FreeBSD Manual Page for date)
For your requirement though, you need the time adjust flag using the -v flag. So the first day of the current month should be
date -v1d -v"$(date '+%m')"m '+%F'
The -v1d is a time adjust flag to move to the first day of the month
In -v"$(date '+%m')"m, we get the current month number using date '+%m' and use it to populate the month adjust field. So e.g. for Aug 2020, its set to -v8m
The '+%F' is to print the date in YYYY-MM-DD format. If its not supported in your date version, use +%Y-%m-%d explicitly.
Or if your requirement is to print the date for all the months
for mon in {1..12}; do
date -v1d -v"$mon"m '+%F'
done

Related

Sends from epoch, for 1 year ago on MacOS / BSD?

I'm trying to calculate the number of seconds since the Epoch, using date on MacOS BSD.
I can get a one year ago date string:
$ date -v -1y
Tue Apr 21 10:44:47 EST 2020
...but I can't figure out how to convert it into seconds since Epoch. Any suggestions?
Add +%s to tell it to print the datetime as seconds since the epoch:
date -v -1y +%s
The + is a date option to set the output format, and %s is strftime format for "seconds since epoch".
Portability note: while the +%s part is pretty standard and portable (though the %s format is not actually required by POSIX), the -v -1y part is wildly nonportable. With GNU date (e.g. on most Linuxes), you'd use something like --date='1 year ago' instead. On NetBSD, -d '1 year ago' works. Check your local man page to see what your system supports.

Covert specific Time to different TIMEZONE in UNIX KSH script

I want to convert specific/Input date to different timezone. I have tried below code.
dateYMD="2019/2/28 12:23:11.46"
timesydney=$(TZ=Australia/Sydney date -d "$dateYMD" +%s)
But above code give me a below error....
date: Not a recognized flag: d
Usage: date [-u] [+"Field Descriptors"]

On MAC OS machine. How can we convert date in 2017-01-09T09:35:26Z to Timestamp using shell script

I tried some conversion methods but failed. I couldn't interpret the input date format correctly.
Below is the command i used to convert
date -j -u -f "%a %b %d %T %Z %Y" "Tue Sep 28 19:35:15 EDT 2010" "+%s"
And i am looking for a command that works for every Time Zone
Well, what a hassle for such a simple question. (PS: I think it was downvoted for not showing an error message, and the use of the OSX tag might better be replaced for macOS if you are on an up-to-date Mac).
The first problem I found out by reading this post. It explains that in order for your command to work the abbreviations need to be in the system language. This can be solved by adding LANG=C in front of your command.
However, your command still delivered the following error:
Failed conversion of ``Tue Sep 28 19:35:15 EDT 2010'' using format ``%a %b %d %T %Z %Y''
date: illegal time format
usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
[-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
Then, when looking into man date I found this line explaining the -f argument:
-f Use input_fmt as the format string to parse the new_date provided rather than using the default
[[[mm]dd]HH]MM[[cc]yy][.ss] format. Parsing is done using strptime(3).
Then, in man strptime I read:
Bugs - The %Z format specifier only accepts time zone abbreviations of
the local
time zone, or the value "GMT". This limitation is because of ambiguity
due to of the over loading of time zone abbreviations. One such example
is EST which is both Eastern Standard Time and Eastern Australia Summer
Time.
So, I was able to execute your command either like so:
LANG=C date -j -u -f '%a %b %d %T %Z %Y' 'Tue Sep 28 19:35:15 GMT 2010' +%s
Or, like so,
TZ=EDT LANG=C date -j -u -f '%a %b %d %T %Z %Y' 'Tue Sep 28 19:35:15 GMT 2010' +%s
But both aren't actually what you where looking for I guess..
You thus seem to be bitten by a known bug in the default macOS version of strptime.
EDIT
However, if you would have a list with the offset of each timezone (the offset towards GMT), you could do something like:
TZ=EDT LANG=C date -juf '%a %b %d %T %z %Y' 'Tue Sep 28 19:35:15 -0400 2010' +%s
Have a look at this post for more possibilities.

Converting date string to date object in BSD MacOSX

In mac osx bsd, date -vmon will convert the current date to Monday's date and date +%w displays day of week.
Say, I have input date 9/14/16 in the format mm/dd/yy. How can I convert this string pattern to a date object so that I could perform date functions like -vmon and +%w on it.
I tried the following: startDate=$(date -jf "%m/%d/%y" "9/14/16") and then tried to perform $startDate +"%w" but it doesn't work. I doubt that the startDate is not date and actually String.
How can I convert the string to date so that I perform date manipulation on it?
Edit: The requirement for doing this is: Say an input date is given. Then corresponding to that date, I want to get the beginning and ending working dates of the week i.e Monday's date and Friday's date. Then I want to get next week's Monday's date and Friday's date. How can I do this?
You need to use date twice, once to convert from the string input to an 'epoch time' (the number of seconds since The Epoch — aka 1970-01-01 00:00:00 +00:00), and once to convert an epoch time to an output format of your choosing:
rdate="9/14/16"
epoch_time=$(date -j -f '%m/%d/%y' "$rdate" +'%s')
date -j -vmon -r "$epoch_time"
date -j -vfri -r "$epoch_time" +'%w'
That gave me the output:
Mon Sep 12 10:14:44 PDT 2016
5
Note that Friday is day 5 of the week, so the output is correct. The use of %w when you specify -vdow seems a little moot; you know that the output will be 5. But you can use any other format characters that you need too.
Note that the time portion is defaulted to the current time. You could add 00:00:00 to the converted date and %H:%M:%S to the conversion format (-f argument) to work with midnight, etc.
You can combine it into one command line:
$ date -j -vmon -r $(date -j -f '%m/%d/%y %H:%M:%S' "$rdate 00:00:00" +'%s') +'%Y-%m-%d %H:%M:%S %w %s'
2016-09-12 00:00:00 1 1473663600
$
The last example on the man page for date on Mac OS X mentions the %s format specifier, which is the key to getting this to work. Well, that and using date twice.
Note that the man page gives synopses:
date [-ju] [-r seconds] [-v [+|-]val[ymwdHMS]] ... [+output_fmt]
date [-jnu] [[[mm]dd]HH]MM[[cc]yy][.ss]
date [-jnu] -f input_fmt new_date [+output_fmt]
date [-d dst] [-t minutes_west]
The 'usage' message is less helpful:
usage: date [-jnu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
[-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
The usage message doesn't show that you can't use -f with -r or -v, whereas the manual is clear that you cannot.
Tested: Mac OS X 10.11.6 El Capitan

shell-script: parse seconds with date

I want to get the date +%m/%d/%Y a different number of days ago.
$(( $(date +%s)- 259200)) gives me the seconds of 3 days ago. The -d parameter doesn't accept the seconds to parse it in the format I want 05/06/2011 (error message: date: invalid date '1307284916').
Is there a way to get date to work?
To get date on linux to accept a simple timestamp for -d, prefix the number with the # sign!
~% date +%s
1307548153
~% date -d #1307548153
Wed Jun 8 16:49:13 IST 2011
On MacOS X, you can use date -r 1307284916 +%m/%d/%Y to get the result you want. If you are not on a BSD-derived system like MacOS X (e.g. if you are using Linux), there doesn't seem to be a simple analogue of date -r. And traditional versions of Unix usually don't even provide the facilities of GNU's date.
If you get really stuck, contact me (see my profile) for a program timestamp:
$ timestamp -T '%m/%d/%Y' 1307284916
1307284916 = 06/05/2011
$ timestamp -n -T '%m/%d/%Y' 1307284916
06/05/2011
$ timestamp -T '%m/%d/%Y' 1307284916 $(( $(date +%s)- 259200))
1307284916 = 06/05/2011
1307288704 = 06/05/2011
$

Resources