Reputation: 1364
VB2012: I am reading data from a legacy system. One of the fields is a time and I am reading that into a DateTime variable. I use the "hhmmt" format to parse out the date with DateTime.ParseExact. The only issue I have is that the legacy system displays A for AM and P for PM with a special case for N for noon. Well .NET doesn't like the N designator so I detect it and change it to P. Works great.
003 0300 AAABBB 845A 1200N
005 1400 CCCDDD 1055A 240P
007 7000 EEEFFF 306P 531P
Now I do some processing and print out the data to a file. I want to print out the times in the format that they are printed in the legacy system. My first thought was to use a custom DateTimeFormatInfo
Dim info As New DateTimeFormatInfo
info.PMDesignator = "N"
and feed that to my string formatter as the IFormatProvider
trip.ArriveTime.ToString("hmmt", info)
But I realize that setting the DateTimeFormatInfo is static and will not be of any use when the time is 12:00P or noon. Is there any way to create a format that will account for this unique scenario and use the N suffix when it is noon but keep the standard A for AM and P for PM for other times?
Update with possible solution:
Imports System.Text.RegularExpressions
Imports System.Globalization
Module mdlExtensions
Private rgxTimePeriod As New Regex("t+")
<System.Runtime.CompilerServices.Extension()> _
Public Function LegacyFormat(dt As DateTime, fmt As String, Optional provider As IFormatProvider = Nothing) As String
Dim formatted As String
If dt.TimeOfDay = New TimeSpan(12, 0, 0) Then
fmt = rgxTimePeriod.Replace(fmt, "N")
End If
If provider Is Nothing Then
formatted = dt.ToString(fmt)
Else
formatted = dt.ToString(fmt, provider)
End If
Return formatted
End Function
<System.Runtime.CompilerServices.Extension()> _
Public Function ToLegacy(dt As DateTime, fmt As String, Optional provider As IFormatProvider = Nothing) As String
'setup the master DateTimeFormatInfo
Dim ci As CultureInfo = CType(provider, CultureInfo)
Dim mstrDtfi As DateTimeFormatInfo
If provider Is Nothing Then
'designate a new DateTimeFormatInfo class if Nothing was passed in
mstrDtfi = New DateTimeFormatInfo
Else
'get a reference to the DateTimeFormatInfo class of the FormatProvider that was passed in
mstrDtfi = ci.DateTimeFormat
End If
'check to see if the time is noon and set a new PMDesignator if it is
If dt.TimeOfDay = New TimeSpan(12, 0, 0) Then
mstrDtfi.PMDesignator = "NN"
End If
'check to see if the time is midnight and set a new AMDesignator if it is
If dt.TimeOfDay = New TimeSpan(0, 0, 0) Then
mstrDtfi.AMDesignator = "MM"
End If
'now format the date string with the proper provider
Dim formattedDate As String
If provider Is Nothing Then
formattedDate = dt.ToString(fmt, mstrDtfi)
Else
formattedDate = dt.ToString(fmt, ci)
End If
Return formattedDate
End Function
End Module
Upvotes: 2
Views: 99
Reputation: 11801
I was aiming for something of a generic solution where the format could change like ddmm hhmmt or hmtt and the overload would take care of the various formats except for the special case of the "t" specifier.
A simple Function can still handle this. Here is an example as an extension method.
Module Extensions
Private rgxTimePeriod As New Regex("t+")
<System.Runtime.CompilerServices.Extension()> _
Public Function LegacyFmt(dt As DateTime, fmt As String, Optional provider As IFormatProvider = Nothing) As String
Dim formatted As String
If dt.TimeOfDay = New TimeSpan(12, 0, 0) Then
fmt = rgxTimePeriod.Replace(fmt, "N")
End If
If provider Is Nothing Then
formatted = dt.ToString(fmt)
Else
formatted = dt.ToString(fmt, provider)
End If
Return formatted
End Function
End Module
?#12:00#.LegacyFmt("hmmt", Globalization.CultureInfo.InvariantCulture)
"1200N"
?now.LegacyFmt("ddmm")
"2551"
?#2:01#.LegacyFmt("hmmt")
?#12:00#.LegacyFmt("hmtt")
"120N"
"201A"
?#2:01#.LegacyFmt("hmtt")
"21AM"
Upvotes: 0