I don't know what is wrong with my code. My code works if the shelf_life is over 1 year. But if the shelf_life is 6 months. It expired very short. It takes only 3 months and it is already expired. But the shelf_life is 6 months. What am I going to do ? What is lacking in my code ?
Week Code: 2138 (2021 week 38)
Shelf_life : 6 months
CTime tt, t11;
CString Cweek, Cyear;
int yy, mm, wknum, yrnum;
tt = CTime::GetCurrentTime();
yy = tt.GetYear();
mm = tt.GetMonth();
wknum = atoi(tt.Format("%U"));
yrnum = atoi(tt.Format("%y"));
t11 = CTime(yy, 1, 1, 0, 0, 0);
if (t11.GetDayOfWeek() != 1)
wknum = wknum + 1;
Cweek.Format("%01d", wknum);
Cyear.Format("%02d", yrnum);
CTimeSpan shelf_no = CTimeSpan(atoi(view->m_pODBCPartsNo->m_shelf_life), 0, 0, 0);
CTime expiration_date = t11 + shelf_no;
Week code is a date code, for example 2138, year 2021(21) week 38(38). Week 38 is around September 19, 2021 to September 25, 2021.
Date displays as 3byte hex value example = 72, 02, 11
Converts to 72 to decimal = 114 + 1900 = 2014, 02 = 02, 11 = 17
So date is 02/17/2014
Bdate comes in as a three byte field, binary so defined
1st byte = year, 2nd byte = mth, 3rd byte = day.
Building a function to call because several dates in data base are of this format.
Secondary function to convert hex to decimal is fnhex2Dec from a library.
Here is code for FixDateBn
let
FixDateBn = (Bdate as binary) =>
let
FixDateBn = BinaryFormat.ByteOrder(
BinaryFormat.Record ([
Yr= BinaryFormat.Byte, //<- the Yr variable is getting Name Yr wasn't recognized.
Mth = BinaryFormat.Byte,
Day = BinaryFormat.Byte ]),
ByteOrder.LittleEndian),
Yrnum = fnhex2Dec(Yr,16)+1900,
Mthnum = fnhex2Dec(Mth,16),
Daynum = fnhex2Dec(Day,16),
Gooddate = #date(Yrnum,Mthnum,Daynum) as date
in
if Bdate is null then null else Gooddate
in
FixDateBn
Appreciate any help.
Here is the sql that converts from hex to regular date. Don't know how to do this in Power Query M language.
CREATE FUNCTION "GetDateFromWDate" (:wDate CHAR(3)) RETURNS DATE AS
BEGIN
DECLARE :tmpdate DATE
SET :tmpdate = '1900-01-01';
IF (:wDate <> null) and (:wDate <> '') THEN
SET :tmpdate = DATEFROMPARTS (ascii(substring(:wDate, 1, 1)) + 1900, ascii(substring(:wDate, 2, 1)), ascii(substring(:wDate, 3, 1)));
END IF;
RETURN :tmpdate;
END
Thanks
Sammy
I am currently stuck on below issue:
I have two tables that I have to work with, one contains financial information for vessels and the other contains arrival and departure time for vessels. I get my data combining multiple excel sheets from different folders:
financialTable
voyageTimeTable
I have to calculate the result for above voyage, and apportion the result over June, July and August for both estimated and updated.
Time in June : 4 hours (20/06/2020 20:00 - 23:59) + 10 days (21/06/2020 00:00 - 30/06/2020 23:59) = 10.1666
Time in July : 31 full days
Time in August: 1 day + 14 hours (02/08/2020 00:00 - 14:00) = 1.5833
Total voyage duration = 10.1666 + 31 + 1.5833 = 42.7499
The result for the "updated" financialItem would be the following:
Result June : 100*(10.1666/42.7499) = 23.7816
Result July : 100*(31/42.7499) = 72.5148
Result August : 100*(1.5833/42.7499) = 3.7036
sum = 100
and then for "estimated" it would be twice of everything above.
This is the format I ideally would like to get:
prorataResultTable
I have to do this for multiple vessels, with multiple timespans and several voyage numbers.
Eagerly awaiting responses, if any. Many thanks in advance.
Brds,
Not sure if you're still looking for an answer, but code below gives me your expected output:
let
financialTable = Table.FromRows({{"A", 1, "profit/loss", 200, 100}}, type table [vesselName = text, vesselNumber = Int64.Type, financialItem = text, estimated = number, updated = number]),
voyageTimeTable = Table.FromRows({{"A", 1, #datetime(2020, 6, 20, 20, 0, 0), #datetime(2020, 8, 2, 14, 0, 0)}}, type table [vesselName = text, vesselNumber = Int64.Type, voyageStartDatetime = datetime, voyageEndDatetime = datetime]),
joined =
let
joined = Table.NestedJoin(financialTable, {"vesselName", "vesselNumber"}, voyageTimeTable, {"vesselName", "vesselNumber"}, "$toExpand", JoinKind.LeftOuter),
expanded = Table.ExpandTableColumn(joined, "$toExpand", {"voyageStartDatetime", "voyageEndDatetime"})
in expanded,
toExpand = Table.AddColumn(joined, "$toExpand", (currentRow as record) =>
let
voyageInclusiveStart = DateTime.From(currentRow[voyageStartDatetime]),
voyageExclusiveEnd = DateTime.From(currentRow[voyageEndDatetime]),
voyageDurationInDays = Duration.TotalDays(voyageExclusiveEnd - voyageInclusiveStart),
createRecordForPeriod = (someInclusiveStart as datetime) => [
inclusiveStart = someInclusiveStart,
exclusiveEnd = List.Min({
DateTime.From(Date.EndOfMonth(DateTime.Date(someInclusiveStart)) + #duration(1, 0, 0, 0)),
voyageExclusiveEnd
}),
durationInDays = Duration.TotalDays(exclusiveEnd - inclusiveStart),
prorataDuration = durationInDays / voyageDurationInDays,
estimated = prorataDuration * currentRow[estimated],
updated = prorataDuration * currentRow[updated],
month = Date.MonthName(DateTime.Date(inclusiveStart)),
year = Date.Year(inclusiveStart)
],
monthlyRecords = List.Generate(
() => createRecordForPeriod(voyageInclusiveStart),
each [inclusiveStart] < voyageExclusiveEnd,
each createRecordForPeriod([exclusiveEnd])
),
toTable = Table.FromRecords(monthlyRecords)
in toTable
),
expanded =
let
dropped = Table.RemoveColumns(toExpand, {"estimated", "updated", "voyageStartDatetime", "voyageEndDatetime"}),
expanded = Table.ExpandTableColumn(dropped, "$toExpand", {"month", "year", "estimated", "updated"})
in expanded
in
expanded
The code tries to:
join financialTable and voyageTimeTable, so that for each vesselName and vesselNumber combination, we know: estimated, updated, voyageStartDatetime and voyageEndDatetime.
generate a list of months for the period between voyageStartDatetime and voyageEndDatetime (which get expanded into new table rows)
for each month (in the list), do all the arithmetic you mention in your question
get rid of some columns (like the old estimated and updated columns)
I recommend testing it with different vesselNames and vesselNumbers from your dataset, just to see if the output is always correct (I think it should be).
You should be able to manually inspect the cells in the $toExpand column (of the toExpand step/expression) to see the nested rows before they get expanded.
I'm trying to parse a string into a struct tm using strptime. Looks easy enough, but it is not filling in the year correctly (yes, I know about the 1900 offset) - after the call, the year is set to 0. Other fields look ok. See below:
struct tm tm;
memset(&tm, 0, sizeof(struct tm));
strptime("Fri Jan 17 09:44:33 UTC 2014", "%a %b %d %H:%M:%S %Z %Y", &tm);
After the strptime call, the tm struct is as follows - note that tm_year=0, where I am expecting it to be 114:
{tm_sec = 33, tm_min = 44, tm_hour = 9, tm_mday = 17, tm_mon = 0, tm_year = 0,
tm_wday = 5, tm_yday = 0, tm_isdst = 0, tm_gmtoff = 0, tm_zone = 0x0}
I'm sure I'm missing something simple - can anyone point it out to me?
On my system (Mac OS X), man strptime has this note about %Z:
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.
And indeed, if I change your "UTC" to "GMT", the code suddenly works. Note that Python for whatever reason is smarter here, and supports "UTC" as well.
I am trying to figure out on making a time from the values i choose (dynamically)
I tried giving a date of 31st march 03:10pm and trying to go back a month with 03:10Pm which is 28th Feb 03:10Pm. But i am getting a value as 04:10Pm.
I set the isdst = -1 to do this bit; but still it fails.
Any ideas.
Tm->tm_mon = ReportMonth;
Tm->tm_mday = ReportEndDay;
Tm->tm_hour = TimeOfDay/60;
Tm->tm_min = TimeOfDay%60;
Tm->tm_sec = 59;
Tm->tm_isdst = -1;