PARSE_DATETIME formatting with day of year - google-cloud-platform

Having an issue with the PARSE_DATETIME function in BigQuery used with the day of year (%j) formatting element. The function seems to ignore the day of year element.
Eg.
select PARSE_DATETIME("%Y%j", "2013243")
returns 2013-01-01T00:00:00, lacking day of year component.
However the reverse function with the same date formatting elements works as expected:
select FORMAT_DATETIME("%Y%j", "2013-02-02T00:00:00")
returns: 2013033
Bug? or user error?
Cheers

I think that this is a bug that could be fixed! there is no logic in it working one way but not opposite!
Meantime, you can use below to achieve goal
#standardSQL
CREATE TEMP FUNCTION PARSE_DATETIME_WITH_DAYS(x STRING) AS (
DATETIME_ADD(PARSE_DATETIME('%Y%j', x), INTERVAL CAST(SUBSTR(x, -3) AS INT64) - 1 DAY)
);
SELECT PARSE_DATETIME_WITH_DAYS('2013243')
with result -
Row f0_
1 2013-08-31T00:00:00

Not a bug, neither an error! PARSE_DATETIME uses a format_string and a STRING representation of a DATETIME to return a DATETIME -> "2013243" does not represent a DATETIME string, not a DATE...
To achieve what you are looking for first get the day number - 1 and add it to date (first day of the year) and format the output to DATETIME
SELECT DATETIME(DATE_ADD((SELECT PARSE_DATE("%Y%j", "2013243")), INTERVAL CAST((SELECT SUBSTR("2013243", -3)) AS INT64) -1 DAY));
Output:
2013-08-31T00:00:00

Related

Age checker 18+ with regular expressions

Can you help me please to do age checker with regular expression? I don't know how to calculate if user is 18 or not.
Input: user's birthday (in format of REGEX)
Output: "welcome" or "come back when you will be 18+"
Here is my code for checking if format is ok and bad:
import re
import datetime
pattern = re.compile("^(0[1-9]|[12][0-9]|3[01])[- \/.,_](0[1-9]|1[012])[- \/.,_](19|20)\d\d")
dob = input('Enter your birthday (dd/mm/yyyy): ')
result = pattern.match(dob)
if pattern.match(dob):
print("format is ok")
else:
print("format is bad")
Thank you in advance!!!
Instead of using regex just try to use the input to create a datetime object - if it works the format is good else input is invalid (see datetime.strptime(date_string, format)).
Once you have it and you have datetime.now() you can easily calculate the age
Okay, so you have the requirement to do it with a regular expression.
Be aware, that this could lead to some edge cases not being covered!
import re
import datetime
pattern = re.compile("^(0[1-9]|[12][0-9]|3[01])[- \/.,_](0[1-9]|1[012])[- \/.,_](19|20)\d\d")
dob = input('Enter your birthday (dd/mm/yyyy): ')
result = pattern.match(dob)
if pattern.match(dob):
print("format is ok")
else:
print("format is bad")
Okay, the regular expression seem to be valid (except the capturing group for the year. You could use Regexr or similiar services if you need to refine it).
Then you can deconstruct the matched groups to get the day, month and year:
[day, month, year] = result.groups() # As mentioned, year is currently either 19 or 20
Then, the next step would be to compare the month against the current month. This will help decide on whether to add a year or not. In case it happens to be the same or an adjacent month, you might want to look at the days, too.
Finally, subtract the current year from the entered one (once you fixed the year capturing group) and do the math.
Since it's an assignment, I won't provide the code for this ;-)

Getting COleDateTime::Format to return "stycznia" instead of "styczeń" for Polish month "January"

I have this method to set the locale to Polish:
void CMeetingScheduleAssistantApp::SetLocale()
{
// https://www.microsoft.com/resources/msdn/goglobal/default.mspx#ISO2
CString strLang[NUM_LANGUAGES] =
{
_T("plk")
// Add more languages here
};
_tsetlocale(LC_ALL, strLang[m_eLanguage - LANGUAGE_ENGLISH]);
}
I have cut the other languages out for brevity. Now, when I format a COleDateTime object and display the month, say January, it shows as:
styczeń
But i want to show it as:
stycznia
Is there a locale setting to adjust the month values returned by the COleDateTime::Format method or locale?
Otherwise I will have to add something manual to override.
The months I would like returned are:
stycznia
lutego
marca
kwietnia
maja
czerwca
lipca
sierpnia
września
października
listopada
grudnia
Update
According to here it states:
Some languages, such as Finnish, German, Polish, and Russian, have
several noun forms. If you plan to use localized names provided by the
system, have a linguist check to make sure you are using them in the
right context. Windows carries both the nominative and genitive forms
of Polish and Russian month names; the form changes depending on
the month name's position in the string relative to the day name.
Windows returns both forms in a single string separated by a null
value. The system carries only one form of each month name or day
name for all other languages.
Now, this is how I am actually formatting my date strings (since I am supporting over 40 languages it is a bit tricky. So, (for English) I start with this format string:
%1 %2!d!-%3!d!
%1 is the month.
%2!d! is the first day value.
%3!d! is the second day value.
If my date needs to cater for crossing over two months, I have:
%1 %2!d!–%3 %4!d!
%1 is the month value.
%2!d! is the first day value.
%3 is the second month value.
%3!d! is the second day value.
The above is used like this:
if (datThisMonday.GetMonth() == datEndOfWeek.GetMonth())
{
strDate.FormatMessage(IDS_STR_TPL_OCLM_WEEK,
datThisMonday.Format(_T("%B")), datThisMonday.GetDay(), datEndOfWeek.GetDay());
}
else
{
strDate.FormatMessage(IDS_STR_TPL_OCLM_WEEK2,
datThisMonday.Format(_T("%B")), datThisMonday.GetDay(),
datEndOfWeek.Format(_T("%B")), datEndOfWeek.GetDay());
}
For Polish, my respective format strings are:
%2!d!-%3!d! %1
%2!d! %1–%4!d! %3
So, I can see that because I am formatting the the date string using FormatMessage and only using the COleDateTime::Format method to parse just the month that it is potentially the cause of the issue.
Since I have two dates in the date string I can't just use a single Date formatting API call (since my date string is representing a week span).
So I checked:
strDate = datThisMonday.Format(_T("%d %B"));
And it made no difference. So I tried this instead:
SYSTEMTIME sTime;
datThisMonday.GetAsSystemTime(sTime);
GetDateFormat(GetThreadLocale(),
DATE_LONGDATE,
&sTime, _T("d MMMM"),
strDate.GetBuffer(_MAX_PATH), _MAX_PATH);
It made no difference. It still shows the date the same way as before. Even if it did display the date correctly it doesn't factor for a date range from two COleDateTime objects.
Confused.
Update 2:
Also tried:
TCHAR szDate[100] = _T("");
GetDateFormatEx(_T("pl"), NULL, &sTime, _T("ddd MMMM"), szDate, 100, NULL);
AfxMessageBox(szDate);
Just will not show the variant.
Update 3
The only way I can get it to show the right date is like this:
GetDateFormatEx(_T("pl"), DATE_LONGDATE, &sTime, NULL, szDate, 100, NULL);
Then the month is correct. Now in the article I referred to it states:
Windows returns both forms in a single string separated by a null
value.
I can't even work out how to access that.
I have encountered other issues but they are distinct from this question, so I will still provide my answer here.
Firstly, I found a document which states that you must have d in the date for it to show the correct version of the month.
Since, I am wanting to display a date range, I start with this:
Polish
Template: %1-%2
Date 1: d
Date 2: d MMMM
Then I format the date:
SYSTEMTIME sysTime;
ENSURE(rDate.GetAsSystemTime(sysTime));
GetDateFormatEx(_T("pl"),
NULL,
&sysTime,
strDateFormat,
strDate.GetBuffer(_MAX_PATH), _MAX_PATH, nullptr);
That displays it correctly. And if the date range spans two months I have:
Template: %1-%2
Date 1: d MMMM
Date 2: d MMMM
It works well.
Since Windows 7, you can also use the LOCALE_RETURN_GENITIVE_NAMES to return the genitive name of a month. Running this :
const wchar_t localeName[] = L"pl-PL";
for (LCTYPE m = LOCALE_SMONTHNAME1; m <= LOCALE_SMONTHNAME12; ++m) {
wchar_t buf[1024];
GetLocaleInfoEx(localeName, m | LOCALE_RETURN_GENITIVE_NAMES, buf, sizeof(buf) / sizeof(*buf));
std::cout << to_utf8(buf) << '\n';
}
Gives the following result :
stycznia
lutego
marca
kwietnia
maja
czerwca
lipca
sierpnia
września
października
listopada
grudnia
which are indeed proper genitive names for months in Polish.

PowerBi - Weeknumber not in the correct order

I'm new to PowerBi and i'm running into the following problem:
Weeknum + year are not shown in the correct order. See the following screenshots:
I've concatenate weeknumber with year based on a column called "PublishDate"
This is my dax query for weeknum:
Weeknum = YEAR ( [PublishDate] ) & "" & WEEKNUM ( [PublishDate], 2 )
I do notice that 1 till 9 are not shown with a 0 infront of it. Could this be causing this?
I agree with getting the '0' in the right place. Once you change the data type from text to a number, if that '0' in't there, it will be out of order as well.
I prefer editing the query and changing the data type from the beginning:
Finding the column that needs a data type change and modifying it there:
[
You can change it from text to whole number.
The problem is that the values are being sorted in alphabetical order, because they are of datatype text. So yes, the fact that '9' does not have a '0' in front of it, does cause your problem. You can solve this by changing the format of the WEEKNUM function like this (also you do not need & "" &):
Weeknum = YEAR ( [PublishDate] ) & FORMAT(WEEKNUM ( [PublishDate], 2 ),"00")

Split a string using regex or other optimized way

I have a very simple string of the form
YYYYMMDDHHMMSS
Basically a full date/time string. Say an example is
20170224134523
Above implies
year: 2017
month: 02
day:24
hour:13
min:45
sec:23
I want to split it so that i can have it in variables (year, month, day, hour, min, sec). This is in Scala I want to. I was thinking should I use a 6-Tuple and on the right side I will use a regex or what as the most efficient way. If I want to do it in a concise way is what I am trying to think. Little bad with regular expressions.
Can anyone help?
I may want to have each variable in the 6-tuple as option type because otherwise that will also do my sanity check? Say if any variable comes out as None, I want to throw an exception
java.text.SimpleDateFormat handles this kind of date parsing well.
scala> val sdf = new SimpleDateFormat("yyyyMMddkkmmss")
sdf: java.text.SimpleDateFormat = java.text.SimpleDateFormat#8e10adc0
scala> val date = sdf.parse("20170224134523")
date: java.util.Date = Fri Feb 24 13:45:23 PST 2017
You can get the date, day, hours, etc from a successful parse of the date as the API shows below.
scala> res0.get
getClass getDate getDay getHours getMinutes getMonth getSeconds getTime getTimezoneOffset getYear
Further, I'd suggest wrapping the parse call in a Try to handle the successful and unsuccessful parsing.
scala> val date = Try(sdf.parse("20170224134523"))
date: scala.util.Try[java.util.Date] = Success(Fri Feb 24 13:45:23 PST 2017)
scala> val date = Try(sdf.parse("asdf"))
date: scala.util.Try[java.util.Date] = Failure(java.text.ParseException: Unparseable date: "asdf")
Here's the same thing using the newer LocalDateTime instead of Date and it's deprecated methods.
LocalDateTime.parse("20170224134523", DateTimeFormatter.ofPattern("yMMddkkmmss"))
java.time.LocalDateTime = 2017-02-24T13:45:23
Because it is a date string it probably makes sense to use a dedicated date parsing library and parse to a datetime type. Fortunatly, java provides a very good one with the java.time package.
val dateTime = LocalDateTime.parse("20170224134523", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))
Which will produce a LocalDateTime object (date and time without a timezone attached). If you need more complicated string parsing you can use a DateTimeFormatterBuilder to customize the date format exactly as you need it.
With such a predictable format you can grab it by position using a substring function (from, to) into a date class.
The regex pattern to grab the sections as groups is:
(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})
Demo

django query to calculate time

The following are the timestamps that is present in the timestamp column of the table userdata.My question is that how to write a query such that i get the output as i need the month name i.2,2010-03 and the total time used in the month
userdata.months.filter().order_by('-timestamp')
'2011-03-07 16:03:01'
'2011-03-07 16:07:04'
'2011-03-06 11:03:01'
'2011-03-08 16:03:01'
'2011-03-04 09:03:01'
'2011-05-16 16:03:01'
'2011-05-18 16:03:01'
'2011-07-16 12:03:01'
'2011-07-17 12:03:01'
'2011-07-17 15:03:01'
something like
my_month = 2 (or whatever you need)
userdata.months.filter(timestamp__month=my_month).aggregate(sum('timestamp__time')
i'm not sure about that timestamp__time, you may search a bit about it, but i think it's correct.
otherwise, you can use a raw query (userdata.months.raw('query here'))