I have a series of data that I get from an access control device, the data is the following:
Cardno, Pin, Verified, DoorID, EventType, InOutState, Time_second
3189959,13978762,4,2,0,0,676132501
Time_second(676132501) should be "2021-01-14 14:58:54.000"
this is my code
Dim sDate As Integer = 676132501
Dim dtDateTime As System.DateTime = New DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc)
dtDateTime = dtDateTime.AddSeconds(sDate).ToLocalTime()
the value returned is : #6/5/1991 10:35:01 AM#, please help
A quick google search of those field names you gave in the question landed on a technical spec doc of something called "PullSDK", which appears to be what you're using. I won't link to it here because I could not find an official source.
The doc gives a formula for decoding these timestamps. Translated to VB.Net it is as follows:
Function DecodeDateTime(ByVal t As Integer) As DateTime
Dim year, month, day, hour, minute, second As Integer
second = t Mod 60
t /= 60
minute = t Mod 60
t /= 60
hour = t Mod 24
t /= 24
day = t Mod 31 + 1
t /= 31
month = t Mod 12 + 1
t /= 12
year = t + 2000
Return New DateTime(year, month, day, hour, minute, second)
End Function
The value you gave, 676132501 is decoded as 2021-01-15 15:35:01 - which is slightly different than your stated expectation. You might want to carefully check the source of that data to verify your assumptions.
As an aside - in evaluating that formula, no amount of adding seconds to some base value would suffice. This is because they've encoded the day into a space that always has 31 values within a month - even for months with less than 31 days. That makes this encoding inefficient, as there will be some values that represent dates that don't actually exist.
Related
Is it possible to return the amount of possible working hours between a start and finish time in MS Project using VBA? For example if the start and end time was from 12pm to 5pm in the same day and there was a lunch break from 12:30p to 1:30pm than the value returned would be 4 hours (instead of the total time passed of 5 hours).
EDIT: Also can you count the total number of shifts (breaks) in a day using VBA?
Question #1: Calculate working hours between two dates
The Microsoft Project application object has a method called DateDifference which does just that--it calculates the working time between two dates and you can optionally supply a calendar object (the project calendar is used by default). The return value is in minutes, so divide by 60 to get hours.
Use the Intermediate Window* to test:
? Application.DateDifference (#3/11/19 12:00 PM#, #3/11/19 5:00 PM#) / 60
4
? Application.DateDifference (#3/11/19 12:00 PM#, #3/11/19 5:00 PM#, ActiveProject.BaseCalendars("24 Hours")) / 60
5
Note: The optional Calendar argument is a calendar object, not the name of a calendar and it must be a calendar in use by the active project.
* From the VB Editor, do Ctrl+G to bring up the Intermediate Window.
Question #2: Calculate the number of shifts for a given day
This function will return the number of shifts for a given day for a particular calendar. If no calendar name is supplied, the project calendar is used.
It works by using the fact that booleans can be converted to integers (False = 0, True = -1) to count the number of true expressions. Specifically, if a shift is used, the Start time is returned as a string representation (e.g. "8:00 AM"), but if the shift is not used, it is returned as an integer (0).
Function ShiftCount(d As Date, Optional calendarName As Variant)
Dim c As Calendar
If IsMissing(calendarName) Then
Set c = ActiveProject.Calendar
Else
Set c = ActiveProject.BaseCalendars(calendarName)
End If
Dim NumShifts As Integer
With c.Period(d)
NumShifts = -CInt(VarType(.Shift1.Start) = vbString) _
- CInt(VarType(.Shift2.Start) = vbString) _
- CInt(VarType(.Shift3.Start) = vbString) _
- CInt(VarType(.Shift4.Start) = vbString) _
- CInt(VarType(.Shift5.Start) = vbString)
End With
ShiftCount = NumShifts
End Function
I'm trying to get a quick ETA on some pre-determined values, 16 and 40. So for example, I need my code to quickly calculate an ETA on an item if it takes 16 hours, but only count the 9-5 (8) hours per day. Obviously I'd need to include the remaining hours of that day, which I have in the code snipped below. However I'm giving myself an ofly sore head trying to work out the best way to proceed with the code. Perhaps someone's got a good idea?
Dim TargetTime as Integer = 16
Dim currentHr As Integer = current.Hour
Dim TodaysRemainingHours As Integer = 0
If currentHr >= 9 AndAlso currentHr < 17 Then
'Count remaining hours
TodaysRemainingHours = (17- currentHr)
Else
'Dont count today
TodaysRemainingHours = 0
End If
My plan is:
TargetTime - TodaysRemainingHours --- Gives the value to count
to.
Somehow calculate the hours based on 9-5 time spans only.
Display lblOutput as: "ETA: 2pm 25/11/2016"
As you can see I know how to get the vaule I need to count to, but I need some help with firstly only counting the hours in each day from 9-5 and then returning the actual hour estimated. This isn't for anything profitable, it's a personal ETA program.
Thank you topshot, your comment helped me work it out! The below code seems to work for me, I haven't identified any issues anyway. I had to make sure I wasn't counting the remaining hours in the current day if the time is past 5pm as well. Thank you.
Dim TargetTime As Integer = 16
Dim current As Datetime = DateTime.now
Dim currentHr As Integer = current.Hour
Dim TodaysRemainingHours As Integer = 0
If currentHr >= 9 AndAlso currentHr < 17 Then
'Count remaining hours
TodaysRemainingHours = (17 - currentHr)
Else
'Dont count today
TodaysRemainingHours = 0
End If
If currentHr >= 9 AndAlso currentHr < 17 Then
'Deduct todays hours from target time.
TargetTime = (TargetTime - TodaysRemainingHours)
'Display results
MsgBox("ETA: " & Now.AddDays(TargetTime / 8))
Else
'Skip todays hours and count from tomorrow morning at 9am
Dim Tomorrow As DateTime = Today.AddDays(1)
Dim TomorrowMorning As TimeSpan = new TimeSpan(09, 00, 0)
Tomorrow = Tomorrow.Date + TomorrowMorning
'Display results
MsgBox("ETA: " & Tomorrow.AddDays(TargetTime / 8))
End If
How can I round off date and time in excel using VBA?
For example, the user selects the value from the calendar which is copied in Cell A6 = "08/25/2016 09:02:00"
I am pulling the data in 15 minutes interval so I want it to be A6 = "08/25/2016 09:00:00"
So if the user selects any date and time that is not in multiple of 15 minutes, it should go back to the previous 15 minute interval value and pull the data.
Pull out the minutes, floor the date portion to get rid of the time, then add it back by building it with TimeSerial:
Private Sub Example()
Dim foo As Date
foo = CDate("08/25/2016 09:02:00")
Dim minutes As Long
minutes = Minute(foo)
minutes = 15 * (minutes \ 15) 'Round down by 15 minute increments
foo = Int(foo) + TimeSerial(Hour(foo), minutes, 0)
Debug.Print foo
End Sub
Edit: Like #Pekka mentions, this can be done with a worksheet formula too - this is the equivalent to the code VBA above:
=INT(A6)+TIME(HOUR(A6),INT(MINUTE(A6) / 15) * 15, 0)
VBA is not necessary. This can be done directly in Excel. =FLOOR(A6,TIME(0,15,0)) will truncate a date time value to the previous 15 minute value.
Excel represents date values as a floating point value since an initial date (around 1900, depending on version) with the time as the fractional portion of the value.
You could, of course, use the same expression in VBA code in the same way.
As Jeeped comments, this is a more self-documenting alternative to the more direct expression =int(A6*24*4)/4/24 initially suggested.
A bit shorter version of the other answers
=MRound(A6, 1/96)
which in VBA can be
[a6] = [MRound(A6, 1/96)]
or to round down
[a6] = [Int(A6*96)/96]
The Problem I am having is with doing time mathematics in VB.
I am currently volunteering at a school and Helping with their Before/Aftercare system
So the goal for before care would be to take a time stamp and compare it to the time school starts that day and find how many half hours are in that given time difference rounding up to the nearest half hour.
For Example. A child Gets to Morning Care at 7:36 School starts at 9:30.
What I want my program to do is
9:30-7:36 = 1 hour 54 minutes
1 hour 54 minutes / 30 minutes = 3.XXX
round that up to 4 multiply by price per hour and my cost is 12
The code I have seems to be off by 15 minutes. I will display the code I use below. Please help by letting me know if there are logic issues or if the method chosen for time math is Poor
'Creating all my variables including half constant half variable times to
compare against
Dim DateIn As DateTime = System.DateTime.Now
Dim Month As Integer = Microsoft.VisualBasic.DateAndTime.Month(DateIn)
Dim Year As Integer = Microsoft.VisualBasic.DateAndTime.Year(DateIn)
Dim Day As Integer = Microsoft.VisualBasic.DateAndTime.Day(DateIn)
Dim DateMorning As New Date(Year, Month, Day, 7, 30, 0)
Dim DateSchoolStart As New Date(Year, Month, Day, 9, 30, 0)
Dim halfHour As System.TimeSpan = New TimeSpan(0, 0, 30, 0)
Dim ticksHalfHour As Long = halfHour.Ticks
Dim count As Integer
Dim cost As Integer
'Portion of a function that calculates cost if the time is in the right zone
If (DateIn >= DateMorning And DateIn < DateSchoolStart) Then
CareTime = DateSchoolStart.Subtract(DateIn)
Dim CareTicks As Long = CareTime.Ticks
count = ReturnCount(CareTicks, ticksHalfHour)
cost = count * price
WriteReport(cost, Year, Month, Day, name)
MessageBox.Show("Welcome to morning care " & name & "!")
Return cost
End If
' function that divides the two longs and does a mod calculation
Function ReturnCount(ByVal tick1 As Long, tick2 As Long) As Integer
If (tick1 Mod tick2 = 0) Then
count = tick1 / tick2
Return count
Else
count = 1 + (tick1 / tick2)
Return count
End If
End Function
I believe this is the relevant portion of the code. If you see a flaw in my logic or have a simpler way of achieving my goal your input would be much appreciated.
I would like some feedback on what's wrong with these codes. I'm trying to output a full week based on a week number. For instance if I input "2014/45" I would like to output all dates spanning from November 2nd to November 8th. Now I need to figure out the first date in that week (hence November 2nd) before grabbing the rest of the days and this is where everything gets messed up for me. This is what I've come up with:
' getyear = 2014, getweek = 45
Dim DateOfFirstWeekDay As DateTime = GetDateOfFirstDayOfWeek(getyear, getweek)
Dim FirstDateInSequence As DateTime = CDate(DateAdd("d", _
CInt(Abs(Integer.Parse(Weekday(DateOfFirstWeekDay, WeekStartsWith))) * -1) + 1, _
DateOfFirstWeekDay)).ToShortDateString()
Protected Friend Shared Function GetDateOfFirstDayOfWeek(ByVal getyear As Nullable(Of Integer), _
ByVal getweek As Nullable(Of Integer)) As DateTime
Dim firstWeekDay As DateTime = GetFirstDayOfWeek(newYearDay)
If getweek = 1 Then
getweek -= 1
End If
Return DateAdd(DateInterval.WeekOfYear, CInt(getweek), firstWeekDay)
End Function
Protected Friend Shared Function GetFirstDayOfWeek(ByVal dt As DateTime) As DateTime
If dt.DayOfWeek = DayOfWeek.Sunday Then
Return dt.AddDays(-6)
Else
Return dt.AddDays(1 - CInt(dt.DayOfWeek))
End If
End Function
As my question implies November 2nd is not the result I get. Instead FirstDateInSequence returns December 22, 2013 when I input 2014/45. It's pretty safe to assume something fails me here. I just can't get my head around it. I'd like your point of view to this. Where should I focus my attention in the code above?
I'm having a hard time quickly following your code logic. So here's mine.
You could start by finding the first day of the first week of that year
Dim d As New DateTime(year, 1, 1)
d = d.AddDays(-d.DayOfWeek)
And then add the number of days (week_number -1) * 7
d = d.AddDays((week_number - 1) * 7)
I do a -1 since I assume that week_number will be equal to 1 to get the first week. Since d is already equal to the first week, we start counting at 0.
To get the last day, just add 6 (or 7) days to the result