Skip to content

Commit eb9ac38

Browse files
authored
Merge pull request #260 from jafin/fix/pdfDate-utc
fix (PdfDate): Specify DateTimeKind UTC type when parsing.
2 parents 4c4b956 + 8b6c1f2 commit eb9ac38

File tree

3 files changed

+53
-23
lines changed

3 files changed

+53
-23
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using FluentAssertions;
3+
using PdfSharpCore.Pdf;
4+
using Xunit;
5+
6+
namespace PdfSharpCore.Test.Pdfs
7+
{
8+
public class PdfDateTests
9+
{
10+
// format for pdf date is generally D:YYYYMMDDHHmmSSOHH'mm'
11+
12+
[Fact]
13+
public void ParseDateString_WithTimezoneOffset()
14+
{
15+
var pdfDate = new PdfDate("D:19981223195200-02'00'");
16+
var expectedDateWithOffset = new DateTimeOffset(new DateTime(1998, 12, 23, 19, 52, 0), new TimeSpan(-2, 0, 0));
17+
pdfDate.Value.ToUniversalTime().Should().Be(expectedDateWithOffset.UtcDateTime);
18+
}
19+
20+
[Fact]
21+
public void ParseDateString_WithNoOffset()
22+
{
23+
var pdfDate = new PdfDate("D:19981223195200Z");
24+
var expectedDateWithOffset = new DateTimeOffset(new DateTime(1998, 12, 23, 19, 52, 0), new TimeSpan(0, 0, 0));
25+
pdfDate.Value.ToUniversalTime().Should().Be(expectedDateWithOffset.UtcDateTime);
26+
}
27+
}
28+
}

PdfSharpCore/Pdf.IO/Parser.cs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,35 +1372,44 @@ private PdfTrailer ReadXRefStream(PdfCrossReferenceTable xrefTable)
13721372
/// <summary>
13731373
/// Parses a PDF date string.
13741374
/// </summary>
1375+
/// <remarks>
1376+
/// Format is
1377+
/// YYYY Year MM month DD day (01-31) HH hour (00-23) mm minute (00-59) ss second (00.59)
1378+
/// O is the relationship of local time to Universal Time (UT), denoted by one of the characters +, -, or Z (see below)
1379+
/// HH followed by ' is the absolute value of the offset from UT in hours (00-23)
1380+
/// mm followed by ' is the absolute value of the offset from UT in minutes (00-59)
1381+
/// For example, December 23, 1998, at 7:52 PM, U.S.Pacific Standard Time, is represented by the string,
1382+
/// D:19981223195200-08'00'
1383+
/// </remarks>
1384+
13751385
internal static DateTime ParseDateTime(string date, DateTime errorValue) // TODO: TryParseDateTime
13761386
{
13771387
DateTime datetime = errorValue;
13781388
try
13791389
{
13801390
if (date.StartsWith("D:"))
13811391
{
1382-
// Format is
13831392
// D:YYYYMMDDHHmmSSOHH'mm'
13841393
// ^2 ^10 ^16 ^20
13851394
int length = date.Length;
13861395
int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0, hh = 0, mm = 0;
13871396
char o = 'Z';
13881397
if (length >= 10)
13891398
{
1390-
year = Int32.Parse(date.Substring(2, 4));
1391-
month = Int32.Parse(date.Substring(6, 2));
1392-
day = Int32.Parse(date.Substring(8, 2));
1399+
year = int.Parse(date.Substring(2, 4));
1400+
month = int.Parse(date.Substring(6, 2));
1401+
day = int.Parse(date.Substring(8, 2));
13931402
if (length >= 16)
13941403
{
1395-
hour = Int32.Parse(date.Substring(10, 2));
1396-
minute = Int32.Parse(date.Substring(12, 2));
1397-
second = Int32.Parse(date.Substring(14, 2));
1404+
hour = int.Parse(date.Substring(10, 2));
1405+
minute = int.Parse(date.Substring(12, 2));
1406+
second = int.Parse(date.Substring(14, 2));
13981407
if (length >= 23)
13991408
{
14001409
if ((o = date[16]) != 'Z')
14011410
{
1402-
hh = Int32.Parse(date.Substring(17, 2));
1403-
mm = Int32.Parse(date.Substring(20, 2));
1411+
hh = int.Parse(date.Substring(17, 2));
1412+
mm = int.Parse(date.Substring(20, 2));
14041413
}
14051414
}
14061415
}
@@ -1417,7 +1426,7 @@ internal static DateTime ParseDateTime(string date, DateTime errorValue) // TOD
14171426
datetime = datetime.Subtract(ts);
14181427
}
14191428
// Now that we converted datetime to UTC, mark it as UTC.
1420-
DateTime.SpecifyKind(datetime, DateTimeKind.Utc);
1429+
datetime = DateTime.SpecifyKind(datetime, DateTimeKind.Utc);
14211430
}
14221431
else
14231432
{

PdfSharpCore/Pdf/PdfDate.cs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,6 @@ namespace PdfSharpCore.Pdf
3939
[DebuggerDisplay("({Value})")]
4040
public sealed class PdfDate : PdfItem
4141
{
42-
/// <summary>
43-
/// Initializes a new instance of the <see cref="PdfDate"/> class.
44-
/// </summary>
45-
public PdfDate()
46-
{ }
47-
4842
/// <summary>
4943
/// Initializes a new instance of the <see cref="PdfDate"/> class.
5044
/// </summary>
@@ -64,20 +58,19 @@ public PdfDate(DateTime value)
6458
/// <summary>
6559
/// Gets the value as DateTime.
6660
/// </summary>
67-
public DateTime Value
68-
{
61+
public DateTime Value =>
6962
// This class must behave like a value type. Therefore it cannot be changed (like System.String).
70-
get { return _value; }
71-
}
72-
DateTime _value;
63+
_value;
64+
65+
readonly DateTime _value;
7366

7467
/// <summary>
7568
/// Returns the value in the PDF date format.
7669
/// </summary>
7770
public override string ToString()
7871
{
79-
string delta = _value.ToString("zzz").Replace(':', '\'');
80-
return String.Format("D:{0:yyyyMMddHHmmss}{1}'", _value, delta);
72+
var delta = _value.ToString("zzz").Replace(':', '\'');
73+
return $"D:{_value:yyyyMMddHHmmss}{delta}'";
8174
}
8275

8376
/// <summary>

0 commit comments

Comments
 (0)