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
A simple Function can still handle this. Here is an example as an extension method.