compare two dates in dd/mm/yyyy format - excel

I have a column where I store dates as dd/mm/yyyy. Then I ask user to input in a form a new date (always as dd/mm/yyyy). I want to compare the input date to the last date that is in the excel already.
If Format(data_mov, "Short Date") < Format(data_last, "Short Date") Then
is not the way to go since it will compare two strings and the test will fail since 03/10/2018 looks smaller than 23/09/2018.
What is the correct way to test them? Something like converting them into timestamps and then compare (but is there something like the unixtimestamp in excel?)

You convert the strings to date and compare them:
' dd/mm/yyyy
' 1234567890
Dim Date1: Date1 = DateSerial(Mid(data_mov, 7, 4), Mid(data_mov, 4, 2), Mid(data_mov, 1, 2))
Dim Date2: Date2 = DateSerial(Mid(data_last, 7, 4), Mid(data_last, 4, 2), Mid(data_last, 1, 2))
If Date1 < Date2 Then
' ...
End If

"What is the correct way to test them?"
IMHO, there is more than one way.
if() with value() will be straightforward.
if() with year(),month(),day(), hour().. is another.
"Something like converting them into timestamps and then compare (but
is there something like the unixtimestamp in excel?)"
The easiest (for me) is using value() function . Then build the desired if() statement on it.
Hope it helps. (:
Microsoft Excel for Windows uses the 1900 date system, by default. Which means the first date is January 1, 1900. a Date and Time function can be used to manipulate the year/date and time/hour/minutes values. The date/time in Excel is stored as a number. Where the decimal part range from 0.0 to 0.99988426 represent 0:00:00 (12:00:00 AM) to 23:59:59 (11:59:59 P.M.), and the integer part range from 0 to 9999 represent year 1900 to year 9999.

Related

How can I format a string into a date: time format?

For example:
2021-08-18T22:24:49-06:00
I want to print this to a more readable format like: 8/18/21 10:24pm
I have tried using the built in DateTime function but it returns an error. Can someone point me in the right direction? I have checked other answers but they all relate to using the aforementioned funciton.
Looking at how your data is formatted and it seems your data is formatted "yyyy-mm-ddThh:mm:ss";so, here is my attempt:
Formula in C1:
=--SUBSTITUTE(LEFT(A1,16),"T"," ")
Then I just formatted the resulting datetime-stamp with:
m/d/yy hh:mm AM/PM
So it remains a numeric value to do your calculations with if needed.
Give a try to below formula-
=TEXT(FILTERXML("<t><s>"&SUBSTITUTE(A1,"T","</s><s>")&"</s></t>","//s[1]")+FILTERXML("<t><s>"&SUBSTITUTE(FILTERXML("<t><s>"&SUBSTITUTE(A1,"T","</s><s>")&"</s></t>","//s[2]"),"-","</s><s>")&"</s></t>","//s[1]"),"M/dd/yyyy hh:mm AM/PM")
The date is in ISO 8601 format. This will parse out the different parts of the date string and convert to a date, assuming that your string is in A1:
=DATEVALUE(LEFT(A1,10))
+TIMEVALUE(MID(A1,12,8))
+TIMEVALUE(RIGHT(A1, 5))
*INT(MID(A1, 20, 1) & 1)
The first part grabs the date, the second part grabs the time, the third part captures the date offset, and the last part captures the sign. If you want to format that, you can do it with the cell formatting or wrap it in TEXT:
=TEXT(
DATEVALUE(LEFT(A1,10))
+TIMEVALUE(MID(A1,12,8))
+TIMEVALUE(RIGHT(A1, 5))
*INT(MID(A1, 20, 1) & 1),
"yyyy-mm-dd hh:mm:ss"
)
Note that if you need to support UTC, that is indicated by Z instead of a time offset, and you would need to modify the formula slightly. If your data always has the same time offset, you could just hardcode it, instead of parsing it out.

VBA Date + TimeValue returns no time

I have a date and time which I assemble into a date + time from strings in the form
date_string = "2020-12-30" 'yyyy-mm-dd
date_code = CDate(date_string)
time_string = "00:00:00" 'hh:mm:ss
time_code = TimeValue(time_string)
date_time = date_code + time_code
Commonly the return looks like 05.01.2019 11:00:00, which is what I expect.
The returned values also all check out as TRUE if I test with IsDate(date_time)
Whenever the time is 00:00:00 however, I only get the date returned with no time appended. I dont quite understand this, since TimeValue(time_string)returns 00:00:00.
So it must be an issue when combining date and time to a date + time string.
Can someone please enlighten me why midnight somehow does no exist in Excel VBA or where my error in creating the time code is?
EDIT:
I try to explain my situation a bit better:
I do this date date/time stuff in code and then but the result in an array in a loop. Only later on it is written to a cell in a table.
By the time is is written into a cell, even custom formatting the cell to "DD.MM.YYYY hh:mm" does not show the time as it is completely missing from the cell value.
Do I neet to apply a format at the point of date_code + time_code?
Sometimes the answer can be so simple. Thanks to Variatus and Paul I checked formatting out.
I applied a date_time = Format(date_code + time_code, "dd.mm.yyyy hh:mm") in my code. Using this, my code runs as expected and 00:00:00 appears as expected, even in the cell values of the Excel table.
When you enter an integer, like 43930, in a cell Excel will record the number as an integer, just as you entered it. You can then proceed to format the cell as #,##0.000 and thereby make the number display as 43930.000. Or you can format that very same number as custom dd mmm yyy hh:mm:ss and display it as 09 Apr 2020 00:00:00. The point is that Excel chose to record the number in its most efficient way, as an integer.
So, if you enter a DateValue + TimeValue which, together, amount to an integer Excel will record the integer correctly. The format in which that integer is displayed in your worksheet is a matter for cell formatting.

Changing format of TODAY() in excel

I'm using today to aquire todays date and then adding a static value to the end of it using the following:
=TODAY()&"T23:00:00"
Which Returns 43202T23:00:00
I really need it in the format 2018-04-12T23:00:00
Any help on this would be great!
There are a couple ways to accomplish this, depending on whether your goal is a formatted String (to display) or a numeric value (such as data type Date) for storing or using with calculations.
If you want a formatted date/time result (to display to the user)...
Use the TEXT worksheet function:
=TEXT(TODAY(),"yyyy-mm-dd")&"T23:00:00"
...the reason this works is because TODAY() returns a Date data type, which is basically just a number representing the date/time, (where 1 = midnight on January 1, 1900, 2 = midnight on January 2, 1900, 2.5 = noon on January 2, 1900,etc).
You can convert the date type to a String (text) with the TEXT function, in whatever format you like. The example above will display today's date as 2018-04-12.
If, for example, you wanted the date portion of the string displayed asApril 12, 2018 then you would instead use:
TEXT(TODAY(),"mmmm d, yyyy")
Note that the TEXT worksheet function (and VBA's Format function) always return Strings, ready to be concatenated with the rest of the String that you're trying to add ("T23:00:00").
If you want to use the result in calculations...
If you instead want the result to be in a Date type, then instead of concatenating a string (produced by the TEXT function) to a string (from "T23:00:00"), you could instead add a date to a date:
=TODAY()+TIME(23,0,0)
or
=TODAY()+TIMEVALUE("23:00")
..and then you can format it as you like to show or hide Y/M/D/H/M/S as necessary with Number Formats (shortcut: Ctrl+1).
More Information:
MSDN : TEXT Function (Excel)
MSDN : TIMEVALUE Function (Excel)
MSDN : TIME Function (Excel)

Why does transposing array with dates in format dd/mm/yy change some dates to mm/dd/yy format?

Behavior:
When I transpose a 1 dimensional array, containing dates, in order to print them to a sheet in it's entirety, some dates are changed from the dd/mm/yy to mm/dd/yyyy.
In particular, when the day of the month:
is less than or equal to 12, such as January 2, 2016 (02/01/16), or May 11, 2016 (11/05/16), then the date is printed with the date format mm/dd/yy and is aligned right.
is greater than or equal to 13, such as April 23, 2016 (23/04/16), or December 17, 2016 (17/12/16), then the date is printed with the date format dd/mm/yyyy and is aligned left.
When I use a for loop to print each date separately, or I do not transpose the array and print each date in the first row of each column however, all dates are printed with the format dd/mm/yy and all dates are aligned right.
Additional information:
I have:
Windows 8.1 (English U.S.)
Office 365 Student (English U.S) (Excel 2016 32 bit)
Locale setting: Netherlands
Code:
Option Explicit
Sub TransposeDatesArray()
Dim arrDates() As Date
Dim i As Variant
ReDim arrDates(0)
For i = CDate("Januari 01, 2016") To CDate("December 31, 2016")
If UBound(arrDates) = 0 Then
ReDim arrDates(1 To 1)
Else
ReDim Preserve arrDates(1 To UBound(arrDates) + 1)
End If
arrDates(UBound(arrDates)) = i
Next
With ThisWorkbook.Worksheets(1)
.Cells.Delete
.Cells(1, 1).Resize(UBound(arrDates)).Value = Application.Transpose(arrDates)
.Cells(1, 2).Resize(UBound(arrDates)).Value2 = Application.Transpose(arrDates)
.Cells(1, 3).Resize(UBound(arrDates)).Formula = Application.Transpose(arrDates)
For i = LBound(arrDates) To UBound(arrDates)
.Cells(i, 4).Value = arrDates(i)
.Cells(i, 5).Value2 = arrDates(i)
.Cells(i, 6).Formula = arrDates(i)
Next
End With
End Sub
Result:
After doing some more research, I have found the following:
It would seem that the Application.Transpose(arrDate) transposes not only the array, but also date values when they are stored as actual date.
Consider the date , 42373 (January 4, 2016)
Debug.Print Format(CDate(42373), "mmmm d, yyyy")
produces januari 4, 2016
Debug.Print Application.Transpose(Format(CDate(42373), "mmmm d, yyyy"))
produces april 1, 2016
It appears that a date value can be transposed when stored as an actual date. The transposing effectively reorders the date from day/month to month/day after which the the month becomes the day and the day becomes the month because the system still uses the day/month format. This can only be done if the day of the month is 12 or less, because after transposing the day becomes the month.
I hit this problem, but interestingly, the date switch (from dd/mm to mm/dd) on transpose only happened when I ran the macro from a toolbar button; if I ran it from inside the VBA editor, or from the Developer menu>Macros dialogue box, it worked fine.
To make it work no matter where I ran the macro from, I added a function before the transpose to convert all dates to strings (looping through my array and using the CStr function), and then converted back from strings to dates after the transpose (another loop and CDate function) - the loops having to be slightly different to account for the transposed dimensions.
Transposing array with Application.Transpose() transforms the "Date" data type into "String". Not able to explain why.
So my suggestion is to transform the Column with "Date" data type into "Long" before you do the Application.Transpose() (simply using CLng).
After that you can either transform it back to "Date" or just set the number format as "Date" for the cells, where you would like to paste the array.
I resolve this issue using .FormulaLocal to write back the array in the sheet.

Multiple Vars for DateDiff VBA

I have a VBA script at the moment that reads in 6 values as integers. 3 values for date, month, and year and 3 of the same type from a different location. I'd like to take the values and check if there has been more than a year to pass between them. DateDiff seems like the easiest way to handle this, however that function reads in the values as one DateValue (ie March 20, 2015) and my values are returned individually (08,08,2015).
I wrote a function that stores each value into a var and then using those individually I concat them into a format that DateValue can use.
This works, however I am curious if there is another(better) way to handle this problem?
Thanks in advance.
The function DateSerial(2015,3,4) will return the date for 3/4/2015, and with both of your dates in that format, you can subtract the one date from the other, and if the (absolute value of the) difference is > 365 then you know that they are over a year apart.
Dim A As Date
A = DateSerial(2015, 3, 4)
Dim B As Date
B = DateSerial(2014, 3, 2)
Dim C As Integer
C = Abs(A - B)
MsgBox C & " days between"

Resources