Forum Discussion

DreDre's avatar
DreDre
Helper II
4 years ago
Solved

Dealing with an offset 24 hour clock

So I am pulling data from an ODBC where events are tracked based on local time in a 24 hour clock of 00:00 - 23:59. When we are evaluating a "Day" we refer to each day as 02:01 - 02:00. The problem I...
  • PaulDBrown's avatar
    4 years ago

    In Power Query, try:

     

    let
        Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("bcu7DcAgEIPhXa5GwmcSXqsg9l8jkKNACY1dfPpbE6hH8QRVnGiuwPyx3X3wMuNtxL1LZvFkNUxK2SjsRMuK/m0RcaS3HtQf", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Date = _t, Time = _t, Value = _t]),
        #"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"Time", type time}, {"Value", Int64.Type}}),
        #"Added Conditional Column" = Table.AddColumn(#"Changed Type", "Custom", each if [Time] < #time(2, 1, 0) then Date.AddDays([Date] as date, -1) else [Date]),
        #"Changed Type1" = Table.TransformColumnTypes(#"Added Conditional Column",{{"Custom", type date}}),
        #"Renamed Columns" = Table.RenameColumns(#"Changed Type1",{{"Custom", "FactDate"}, {"Date", "SourceDate"}})
    in
        #"Renamed Columns"

     

    to get:

    (You can in fact remove the original SourceDate column as the last step in the query. I've left it in for illustration purposes) 

    To order Time so that 00:00 to 02:00 are set at the end of the day, create a dimension table for time including a column to sort the time by:

     

    let
        Source = List.Times(#time(0, 0, 0), 1440, #duration(0, 0, 1, 0)),
        #"Converted to Table" = Table.FromList(Source, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
        #"Renamed Columns" = Table.RenameColumns(#"Converted to Table",{{"Column1", "Time"}}),
        #"Changed Type2" = Table.TransformColumnTypes(#"Renamed Columns",{{"Time", type time}}),
        #"Added Custom Column" = Table.AddColumn(#"Changed Type2", "Number", each let splitTime = Splitter.SplitTextByDelimiter(":", QuoteStyle.None)(Text.From([Time], "es-ES")) in Text.Combine({Text.Combine(splitTime), "00"}), type text),
        #"Changed Type" = Table.TransformColumnTypes(#"Added Custom Column",{{"Number", Int64.Type}}),
        #"Added Conditional Column" = Table.AddColumn(#"Changed Type", "26 hour day", each if [Number] < 20001 then ([Number] + 240000)/100 else [Number]/100),
        #"Removed Columns" = Table.RemoveColumns(#"Added Conditional Column",{"Number"}),
        #"Changed Type1" = Table.TransformColumnTypes(#"Removed Columns",{{"26 hour day", Int64.Type}})
    in
        #"Changed Type1"

     

    And sort the Time column by the  26 hour day column once loaded in the model and you can use either in visuals: 

    Then create a Date table, and join it in a one-to-many relationship with the newly created date field (FactDate in my example) and do the same between the Time fields in the dimension table and fact table. The model looks like this.

    Next, in model view, select the 26 hour day column in the field list and set the format to custom using:

     

     

    And here is an example of what you can get setting the axis as categorical:

    The advantage of using the 26 hour day column is that IMHO it is clearer and that you can use it in a continuos axis, whereas if you use the Time column in a continuous axis, the default time order overides the order established by the "Order column by" function:

     I've attached a sample PBIX file

     

     

     

  • DreDre's avatar
    4 years ago

    hnguy71 You are right, I should have started there, but after a little more tweaking I was able to find the less desireable result where it will show at the start of the day by adjusting my formula to be :

     

    =if Time.From([DepLoc]) < #time(02, 00, 00) then [DepLoc] - #duration(1,0,0,0) else [DepLoc]

    (If the time in DepLoc was less thatn 2am then subtract 1 day of time otherwise show DepLoc as is)

     

    My data in DepLoc looks like ( 1/25/2021 12:10:00 AM ) and is in the format of "Date/Time"

     

    PaulDBrown I am very interested in how you were able to accomplish this as I think that a 26 hour day would be a better user experience. Looking at the PBIX file you have the data starting as two columns, one with date and another with time. I think that I am going to play with this to see if I can use this same structure for my data. I really appreciate such a detailed answer! I can definitely see how this would also answer my question, Thank-you 🙂