I'd like to sort an array (nextbirthdays) by a date value which is given. Unlike just ordering the date itself, I'd like to sort by the day given. In this case I'd like to display the birthdays of users. The dataset given only contains users with their birthday of today plus 7 days.
the dataset itself could look something like this:
Birthday | Username
--------------+-----------
01. Apr 1953 | User 1
04. Apr 1970 | User 2
02. Apr 1992 | User 3
02. Apr 2002 | User 4
01. Apr 1993 | User 5
When using nextbirthdays|sort twig correctly sorts the dates (by newest to olderst or the other way around) but I'd like to sort by the actual day, then month, then year of the date.
Birthday | Username
--------------+-----------
01. Apr 1993 | User 5
01. Apr 1953 | User 1
02. Apr 2002 | User 4
02. Apr 1992 | User 3
04. Apr 1970 | User 2
Original Code:
<ul>
{% for nextbd in nextbirthdays %}
<li><span class="text-muted mr-3">{{ nextbd.birthday|date("d. M Y") }}: </span>
{% if nextbd.birthday|date("d.m") == "now"|date("d.m") %}
<b>{{ nextbd.firstname }} {{ nextbd.lastname }}</b>
{% else %}
{{ nextbd.firstname }} {{ nextbd.lastname }}
{% endif %}
{% endfor %}
</ul>
Sort & Map:
When trying to adapt the sort function from twig using the statement below the birthdays don't show up anymore.
{% for nextbd in nextbirthdays|sort((a, b) => a.birthday <=> b.birthday)|column('birthday') %}
<!-- rest of the code is unchanged -->
{% endfor %}
You do have two issues in your code:
|column('birthday'): using this filter, you'll limit your array to the column birthday only, so you won't get the first or last name anymore.
Your requirement is more complex than what you think it is:
01. Apr sorted before 02. Apr means your are doing an ascending sort on the day and month
01. Apr 1993 sorted before 01. Apr 1953 means you are doing a descending sorting on the year
So, your condition should be:
a.birthday|date('dm') > b.birthday|date('dm') or (a.birthday|date('dm') == b.birthday|date('dm') and a.birthday|date('Y') < b.birthday|date('Y'))
Giving a for loop:
{% for nextbd in nextbirthdays|sort((a, b) => a.birthday|date('dm') > b.birthday|date('dm') or (a.birthday|date('dm') == b.birthday|date('dm') and a.birthday|date('Y') < b.birthday|date('Y'))) %}
{# rest of the code is unchanged #}
{% endfor %}
This can be tested here: https://twigfiddle.com/of3cbi
I want to convert the string "Nov 26 23:59:00 2022 GMT" to a timestamp 1669507140000. I checked the man date to get this command:
date -d "Nov 26 23:59:00 2022 GMT" +"%s"
But his returns: 1669507140 (the last 3 zeros are missing).
Can anyone tell me what I am missing? Thank you.
The version of the date command that I have on my system (YMMV) will show us what it is doing if we add the --debug flag to our invocation...
$ date -d "Nov 26 23:59:00 2022 GMT" +"%s" --debug
date: parsed date part: (Y-M-D) 2020-11-26
date: parsed time part: 23:59:00
date: parsed number part: year: 2022
date: parsed zone part: UTC+00
date: input timezone: parsed date/time string (+00)
date: using specified time as starting value: '23:59:00'
date: starting date/time: '(Y-M-D) 2022-11-26 23:59:00 TZ=+00'
date: '(Y-M-D) 2022-11-26 23:59:00 TZ=+00' = 1669507140 epoch-seconds
date: timezone: system default
date: final: 1669507140.000000000 (epoch-seconds)
date: final: (Y-M-D) 2022-11-26 23:59:00 (UTC)
date: final: (Y-M-D) 2022-11-27 07:59:00 (UTC+08)
1669507140
The debug log shows us the %s format will result in displaying seconds since epoch. Alternatively, nanosecond precision can be achieved using a modified format string (I added a .001 in the date string to prove it works):
$ date -d "Nov 26 23:59:00.001 2022 GMT" +"%s.%N" --debug
date: parsed date part: (Y-M-D) 2020-11-26
date: parsed time part: 23:59:00
date: parsed number part: year: 2022
date: parsed zone part: UTC+00
date: input timezone: parsed date/time string (+00)
date: using specified time as starting value: '23:59:00'
date: starting date/time: '(Y-M-D) 2022-11-26 23:59:00 TZ=+00'
date: '(Y-M-D) 2022-11-26 23:59:00 TZ=+00' = 1669507140 epoch-seconds
date: timezone: system default
date: final: 1669507140.001000000 (epoch-seconds)
date: final: (Y-M-D) 2022-11-26 23:59:00 (UTC)
date: final: (Y-M-D) 2022-11-27 07:59:00 (UTC+08)
1669507140.001000000
We can use a pipe to awk to round up to milliseconds for our final form (note I used .0005 in the date string here to show rounding):
$ date -d "Nov 26 23:59:00.0005 2022 GMT" +"%s.%N" | awk '{ printf("%d\n", int($0 * 1000) + (int($0 * 2000) % 2)) }'
1669507140001
One further note.... The following is the version of the date command I am using:
$ date --version
date (GNU coreutils) 8.30
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by David MacKenzie.
I am processing a file and filtering out certain fields from it. Then, I am converting the whole result to a CSV file. However, the last column that I am filtering out is the epoch timestamp (upto millisecond).
Searching around, I found that I can use the strftime function in jq for conversion, however; when applying the | strftime inside the whole array, it applies the function to all the values.
TZ='Asia/Kolkata' grep $id ~/hhfh.log | grep -oE '\{.+' | jq -r '[.highPrice, .lowPrice, .openPrice, .closePrice, .volumeTradedToday, .totalBuyQuantity, .totalSellQuantity, .tickTimestamp | strftime("%B %d %Y %I:%M%p %Z")]' | jq -r 'map(tostring) | join(", ")'
Can I modify this so that strftime("%B %d %Y %I:%M%p %Z") only applies to the .tickTimestmap value? If not, Would I have to depend on awk?
Log lines from hhfh.log:
2018-03-06 03:30:04,938 DEBUG KiteTickerSourceLogic [ReadingThread] TickData: {"mode":"full","tradable":false,"instrumentToken":2997505,"lastTradedPrice":740.0,"highPrice":0.0,"lowPrice":0.0,"openPrice":731.5,"closePrice":739.9,"change":0.01351533991080183,"lastTradedQuantity":23.0,"averageTradePrice":0.0,"volumeTradedToday":12.0,"totalBuyQuantity":285.0,"totalSellQuantity":1469.0,"lastTradedTime":1520245282000,"oi":0.0,"tickTimestamp":1520307004000,"openInterestDayHigh":0.0,"openInterestDayLow":0.0,"marketDepth":{"buy":[{"quantity":1,"price":735.55,"orders":1},{"quantity":86,"price":731.5,"orders":1},{"quantity":168,"price":731.0,"orders":1},{"quantity":25,"price":730.1,"orders":1},{"quantity":0,"price":0.0,"orders":0}],"sell":[{"quantity":550,"price":743.6,"orders":1},{"quantity":550,"price":746.6,"orders":1},{"quantity":10,"price":750.0,"orders":1},{"quantity":25,"price":777.0,"orders":1},{"quantity":12,"price":-0.01,"orders":1}]}}
What I am currently generating:
January 01 1970 12:05:08AM UTC, January 01 1970 12:05:02AM UTC, January 01 1970 12:05:04AM UTC, January 01 1970 12:05:06AM UTC, January 19 1970 08:56:53AM UTC, January 01 1970 04:39:20AM UTC, January 01 1970 12:00:00AM UTC, August 31 50144 10:33:20AM UTC
What it should be like:
751.95, 734.1, 745.45, 742.8, 1659987, 6358, 0, <time in IST zone>
Simply use parentheses:
(.tickTimestamp | strftime("%B %d %Y %I:%M%p %Z"))
If you want the time relative to TZ, use strflocaltime, which however requires a more recent version of jq than 1.5.
I want to find a date that is 57 –working– days after an arbitrary date using date or bash. For instance,
today is august 21st,
reference date is july 15th,
what days will be 57 working days after july 15th?
This should work to just get all days
date -d '7/15/14 +57 days'
To get number of work days (M..F) you can do something lazy like this
#!/bin/bash
days=0
for ((i=1;i>0;i++)) do
future=$(date -d "7/15/14 +$i days" '+%w')
((future!=0 && future!=6)) && ((days++)) # ignore sunday (0) and saturday (6)
((days==57)) && date -d "7/15/14 +$i days" && break
done
e.g.
> ./abovescript
> Thu Oct 2 00:00:00 CDT 2014
Weird solution:
day=21
mon=8
year=2014
days=4
curl -s "http://www.timeanddate.com/scripts/dateserver.php?mode=addweekdays&d1=$day&m1=$mon&y1=$year&type=add&ad=$days&atyp=0&ach=3" | sed -n 's|.*<h2>Result: \(.*\)</h2>.*|\1|p'
prints
Wednesday, August 27, 2014
the date after 4 working days from 2014.08.21
for the
day=15
mon=7
year=2014
days=57
prints
Friday, October 3, 2014
This question already has answers here:
Using `date` command to get previous, current and next month
(5 answers)
Closed 8 years ago.
I have been using the command:
date --date='1 months ago' +%b
To get the month name of the month it was a month ago, but have realised today as it is the 31st that this command actually gives me the month name it was 4 weeks ago.
Is there any way to get the calendar month that it was 1 month ago, or indeed n months ago as I can see that the discrepancy will be greater as the number of months is longer.
Date calculations that depend on the number of days in the month are tricky. A hybrid approach, using month numbers and a lookup table, will probably work best.
months=("" Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)
echo ${months[$(date +%m) - 1 ]}
[[ $(date +%d) == "31" ]] && date -d'-31 day' +%b || date -d'-1 month' +%b
test with today:
kent$ date
Thu Jul 31 17:34:27 CEST 2014
kent$ [[ $(date +%d) == "31" ]] && date -d'-31 day' +%b || date -d'-1 month' +%b
Jun
try this one line
#if the month before 30 days is the same of the actual month ,then return the month before 31 days
[[ `date --date='30 day ago' +%b` == `date +%b` ]] && echo `date --date='31 day ago' +%b` || echo `date --date='30 day ago' +%b`