Reputation: 705
I am interested in using NLog in my C# project and found it great, but
In my country Clients works with "Persian Calendar".
As you know Microsoft developed a library to support named "C# Persian Calendar class".
I need Persian calendar date format in two places
1-Message Time stamp
2-Date based File Name
How to force NLog to use " C# Persian Calendar class" in above usages?
Thanks
Upvotes: 2
Views: 536
Reputation: 27618
You don't necessarily have to modify NLog source and build it yourself. You could probably write your own PersianDateLayoutRenderer. It is then a simple matter of configuring NLog to use your layout renderer rather than the one of NLog's built in layout renderers. When you upgrade to a new version NLog, your layout renderer should still work.
Here is an example that combines NLog's LongDateLayoutRenderer and the .NET Persian Calendar. I don't know if formatting is available for Persian dates, so I just hardcoded a format.
You can configure this in the NLog.config file by using ${persianlongdate} rather than ${shortdate}, ${longdate}, or ${date}.
I haven't tried to build or run this, but it should be pretty close. You could easily modify it to use Jon's Noda Time if you decide to try that route.
You can find the source for NLog's LongDateLayoutRenderer (and DateLayoutRenderer and ShortDateLayoutRenderer) here:
https://github.com/NLog/NLog/blob/master/src/NLog/LayoutRenderers
namespace MyLayoutRenderers
{
using System.ComponentModel;
using System.Globalization;
using System.Text;
using NLog.Config;
[LayoutRenderer("persianlongdate")]
[ThreadAgnostic]
public class PersianSLongDateLayoutRenderer : LayoutRenderer
{
PersianCalendar pc = new PersianCalendar();
/// <summary>
/// Gets or sets a value indicating whether to output UTC time instead of local time.
/// </summary>
/// <docgen category='Rendering Options' order='10' />
[DefaultValue(false)]
public bool UniversalTime { get; set; }
/// <summary>
/// Renders the current short date string (yyyy-MM-dd) and appends it to the specified <see cref="StringBuilder" />.
/// </summary>
/// <param name="builder">The <see cref="StringBuilder"/> to append the rendered data to.</param>
/// <param name="logEvent">Logging event.</param>
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
DateTime ts = logEvent.TimeStamp;
//Not sure if UniversalTime makes sense for PersianCalendar. Do you?
if (this.UniversalTime)
{
ts = ts.ToUniversalTime();
}
builder.Append(String.Format("{0}-{1}-{2}-{3}:{4}-{5}-{6}",
pc.GetDayOfWeek(ts),
pc.GetMonth(ts),
pc.GetDayOfMonth(ts),
pc.GetYear(ts),
pc.GetHour(ts),
pc.GetMinute(ts),
pc.GetSecond(ts));
}
}
}
Good luck!
Upvotes: 2
Reputation: 1502835
There are two difficulties with this:
DateTime.ToString
won't work anyway :(You'll definitely need to look into the source code (or at least documentation) for NLog to find out whether there's a way of configuring the formatting. Once you've worked out how to get your own code to be executed there - e.g. by writing your own subclass, potentially - you'll need to work out how to do the actualy formatting.
You could do this using the BCL, calling into PersianCalendar
and doing simple numeric formatting. Or you could use my Noda Time library, which also has Persian calendar support (as of Noda Time 1.3). You'd want something like:
var gregorian = new LocalDate(2014, 11, 6); // Or whatever
var persian = gregorian.WithCalendar(CalendarSystem.GetPersianCalendar());
var text = persian.ToString("yyyy-MM-dd"); // Or create a LocalDatePattern
Upvotes: 2