/*---------------------------------------------------------------------- | TestDateFromTimeStringANSI +---------------------------------------------------------------------*/ static void TestDateFromTimeStringANSI() { NPT_DateTime date; /* Valid date */ SHOULD_SUCCEED(date.FromString("Fri Apr 14 12:01:10 2006", NPT_DateTime::FORMAT_ANSI)); SHOULD_EQUAL_I(date.m_Year , 2006); SHOULD_EQUAL_I(date.m_Month , 4); SHOULD_EQUAL_I(date.m_Day , 14); SHOULD_EQUAL_I(date.m_Hours , 12); SHOULD_EQUAL_I(date.m_Minutes , 1); SHOULD_EQUAL_I(date.m_Seconds , 10); SHOULD_EQUAL_I(date.m_NanoSeconds , 0); SHOULD_EQUAL_I(date.m_TimeZone , 0); /* Valid date with space in the days */ SHOULD_SUCCEED(date.FromString("Fri Apr 7 12:01:10 2006", NPT_DateTime::FORMAT_ANSI)); SHOULD_EQUAL_I(date.m_Year , 2006); SHOULD_EQUAL_I(date.m_Month , 4); SHOULD_EQUAL_I(date.m_Day , 7); SHOULD_EQUAL_I(date.m_Hours , 12); SHOULD_EQUAL_I(date.m_Minutes , 1); SHOULD_EQUAL_I(date.m_Seconds , 10); SHOULD_EQUAL_I(date.m_NanoSeconds , 0); SHOULD_EQUAL_I(date.m_TimeZone , 0); /* Wrong weekday */ SHOULD_FAIL(date.FromString("Wed Apr 14 12:01:10 2006", NPT_DateTime::FORMAT_ANSI)); /* Wrong year length */ SHOULD_FAIL(date.FromString("Mon Apr 14 12:01:10 95", NPT_DateTime::FORMAT_ANSI)); }
/*---------------------------------------------------------------------- | TestDateFromTimeStringRFC_1123 +---------------------------------------------------------------------*/ static void TestDateFromTimeStringRFC_1123() { NPT_DateTime date; /* Valid date */ SHOULD_SUCCEED(date.FromString("Fri, 14 Apr 2006 12:01:10 UT", NPT_DateTime::FORMAT_RFC_1123)); SHOULD_EQUAL_I(date.m_Year , 2006); SHOULD_EQUAL_I(date.m_Month , 4); SHOULD_EQUAL_I(date.m_Day , 14); SHOULD_EQUAL_I(date.m_Hours , 12); SHOULD_EQUAL_I(date.m_Minutes , 1); SHOULD_EQUAL_I(date.m_Seconds , 10); SHOULD_EQUAL_I(date.m_NanoSeconds , 0); SHOULD_EQUAL_I(date.m_TimeZone , 0); /* Valid date with timezone*/ SHOULD_SUCCEED(date.FromString("Fri, 14 Apr 2006 12:01:10 GMT", NPT_DateTime::FORMAT_RFC_1123)); SHOULD_EQUAL_I(date.m_Year , 2006); SHOULD_EQUAL_I(date.m_Month , 4); SHOULD_EQUAL_I(date.m_Day , 14); SHOULD_EQUAL_I(date.m_Hours , 12); SHOULD_EQUAL_I(date.m_Minutes , 1); SHOULD_EQUAL_I(date.m_Seconds , 10); SHOULD_EQUAL_I(date.m_NanoSeconds , 0); SHOULD_EQUAL_I(date.m_TimeZone , 0); /* Valid date with timezone*/ SHOULD_SUCCEED(date.FromString("Fri, 14 Apr 2006 12:01:10 +0800", NPT_DateTime::FORMAT_RFC_1123)); SHOULD_EQUAL_I(date.m_Year , 2006); SHOULD_EQUAL_I(date.m_Month , 4); SHOULD_EQUAL_I(date.m_Day , 14); SHOULD_EQUAL_I(date.m_Hours , 12); SHOULD_EQUAL_I(date.m_Minutes , 1); SHOULD_EQUAL_I(date.m_Seconds , 10); SHOULD_EQUAL_I(date.m_NanoSeconds , 0); SHOULD_EQUAL_I(date.m_TimeZone , 8*60); /* Valid date, short year */ SHOULD_SUCCEED(date.FromString("Fri, 14 Apr 95 12:01:10 GMT", NPT_DateTime::FORMAT_RFC_1123)); SHOULD_EQUAL_I(date.m_Year , 1995); SHOULD_EQUAL_I(date.m_Month , 4); SHOULD_EQUAL_I(date.m_Day , 14); SHOULD_EQUAL_I(date.m_Hours , 12); SHOULD_EQUAL_I(date.m_Minutes , 1); SHOULD_EQUAL_I(date.m_Seconds , 10); SHOULD_EQUAL_I(date.m_NanoSeconds , 0); SHOULD_EQUAL_I(date.m_TimeZone , 0); /* Wrong day name */ SHOULD_FAIL(date.FromString("Friday, 14 Apr 95 12:01:10 GMT", NPT_DateTime::FORMAT_RFC_1123)); /* Wrong weekday */ SHOULD_FAIL(date.FromString("Wed, 14 Apr 2006 12:01:10 GMT", NPT_DateTime::FORMAT_RFC_1123)); /* Wrong year length */ SHOULD_FAIL(date.FromString("Mon, 14 Apr 95 12:01:10 GMT", NPT_DateTime::FORMAT_RFC_1123)); }
/*---------------------------------------------------------------------- | TestRandom +---------------------------------------------------------------------*/ static void TestRandom() { for (unsigned int i=0; i<10000; i++) { NPT_TimeStamp ts((double)NPT_System::GetRandomInteger()); NPT_TimeStamp ts2; NPT_DateTime date; SHOULD_SUCCEED(date.FromTimeStamp(ts, false)); SHOULD_SUCCEED(date.ToTimeStamp(ts2)); NPT_String ds; NPT_DateTime ndate; ds = date.ToString(NPT_DateTime::FORMAT_ANSI); ndate.FromString(ds); //SHOULD_EQUAL(date, ndate); SHOULD_SUCCEED(ndate.ToTimeStamp(ts2)); SHOULD_EQUAL_F((double)ts2.ToSeconds(), (double)ts.ToSeconds()); ds = date.ToString(NPT_DateTime::FORMAT_W3C); ndate.FromString(ds); //SHOULD_EQUAL(date, ndate); SHOULD_SUCCEED(ndate.ToTimeStamp(ts2)); SHOULD_EQUAL_F((double)ts2.ToSeconds(), (double)ts.ToSeconds()); ds = date.ToString(NPT_DateTime::FORMAT_RFC_1123); ndate.FromString(ds); //SHOULD_EQUAL(date, ndate); SHOULD_SUCCEED(ndate.ToTimeStamp(ts2)); SHOULD_EQUAL_F((double)ts2.ToSeconds(), (double)ts.ToSeconds()); ds = date.ToString(NPT_DateTime::FORMAT_RFC_1036); ndate.FromString(ds); //SHOULD_EQUAL(date, ndate); SHOULD_SUCCEED(ndate.ToTimeStamp(ts2)); SHOULD_EQUAL_F((double)ts2.ToSeconds(), (double)ts.ToSeconds()); } }
/*---------------------------------------------------------------------- | PLT_MediaObject::FromDidl +---------------------------------------------------------------------*/ NPT_Result PLT_MediaObject::FromDidl(NPT_XmlElementNode* entry) { NPT_String str, xml; NPT_Array<NPT_XmlElementNode*> children; NPT_Result res; // check if item is restricted (is default true?) if (NPT_SUCCEEDED(PLT_XmlHelper::GetAttribute(entry, "restricted", str, "", 5))) { m_Restricted = PLT_Service::IsTrue(str); } // read non-required elements PLT_XmlHelper::GetChildText(entry, "creator", m_Creator, didl_namespace_dc, 256); PLT_XmlHelper::GetChildText(entry, "date", m_Date, didl_namespace_dc, 256); // parse date and make sure it's valid NPT_String parsed_date; for (int format=0; format<=NPT_DateTime::FORMAT_RFC_1036; format++) { NPT_DateTime date; if (NPT_SUCCEEDED(date.FromString(m_Date, (NPT_DateTime::Format)format))) { parsed_date = date.ToString((NPT_DateTime::Format)format); break; } } m_Date = parsed_date; res = PLT_XmlHelper::GetAttribute(entry, "id", m_ObjectID); NPT_CHECK_SEVERE(res); res = PLT_XmlHelper::GetAttribute(entry, "parentID", m_ParentID); NPT_CHECK_SEVERE(res); PLT_XmlHelper::GetAttribute(entry, "refID", m_ReferenceID); res = PLT_XmlHelper::GetChildText(entry, "title", m_Title, didl_namespace_dc); NPT_CHECK_SEVERE(res); res = PLT_XmlHelper::GetChildText(entry, "class", m_ObjectClass.type, didl_namespace_upnp); NPT_CHECK_SEVERE(res); // DLNA 7.3.17.3 max bytes for dc:title and upnp:class is 256 bytes m_Title = m_Title.SubString(0, 256); m_ObjectClass.type = m_ObjectClass.type.SubString(0, 256); children.Clear(); PLT_XmlHelper::GetChildren(entry, children, "artist", didl_namespace_upnp); m_People.artists.FromDidl(children); children.Clear(); PLT_XmlHelper::GetChildren(entry, children, "author", didl_namespace_upnp); m_People.authors.FromDidl(children); children.Clear(); PLT_XmlHelper::GetChildren(entry, children, "actors", didl_namespace_upnp); m_People.actors.FromDidl(children); children.Clear(); PLT_XmlHelper::GetChildren(entry, children, "director", didl_namespace_upnp); m_People.directors.FromDidl(children); PLT_XmlHelper::GetChildText(entry, "album", m_Affiliation.album, didl_namespace_upnp, 256); PLT_XmlHelper::GetChildText(entry, "programTitle", m_Recorded.program_title, didl_namespace_upnp); PLT_XmlHelper::GetChildText(entry, "seriesTitle", m_Recorded.series_title, didl_namespace_upnp); PLT_XmlHelper::GetChildText(entry, "episodeNumber", str, didl_namespace_upnp); NPT_UInt32 value; if (NPT_FAILED(str.ToInteger(value))) value = 0; m_Recorded.episode_number = value; children.Clear(); PLT_XmlHelper::GetChildren(entry, children, "genre", didl_namespace_upnp); for (NPT_Cardinal i=0; i<children.GetItemCount(); i++) { if (children[i]->GetText()) { m_Affiliation.genres.Add(children[i]->GetText()->SubString(0, 256)); } } PLT_XmlHelper::GetChildText(entry, "description", m_Description.description, didl_namespace_dc); PLT_XmlHelper::GetChildText(entry, "longDescription", m_Description.long_description, didl_namespace_upnp); PLT_XmlHelper::GetChildText(entry, "icon", m_Description.icon_uri, didl_namespace_upnp); PLT_XmlHelper::GetChildText(entry, "rating", m_Description.rating, didl_namespace_upnp); PLT_XmlHelper::GetChildText(entry, "toc", m_MiscInfo.toc, didl_namespace_upnp); // album arts children.Clear(); PLT_XmlHelper::GetChildren(entry, children, "albumArtURI", didl_namespace_upnp); for (NPT_Cardinal i=0; i<children.GetItemCount(); i++) { if (children[i]->GetText()) { PLT_AlbumArtInfo info; info.uri = children[i]->GetText()->SubString(0, 1024); PLT_XmlHelper::GetAttribute(children[i], "profileID", info.dlna_profile, didl_namespace_dlna); m_ExtraInfo.album_arts.Add(info); } } PLT_XmlHelper::GetChildText(entry, "originalTrackNumber", str, didl_namespace_upnp); if (NPT_FAILED(str.ToInteger(value))) value = 0; m_MiscInfo.original_track_number = value; PLT_XmlHelper::GetChildText(entry, "lastPlaybackPosition", str, didl_namespace_upnp); if (NPT_FAILED(str.ToInteger(value))) value = 0; m_MiscInfo.last_position = value; PLT_XmlHelper::GetChildText(entry, "lastPlaybackTime", m_MiscInfo.last_time, didl_namespace_dc, 256); NPT_String parsed_last_time; for (int format=0; format<=NPT_DateTime::FORMAT_RFC_1036; format++) { NPT_DateTime date; if (NPT_SUCCEEDED(date.FromString(m_MiscInfo.last_time, (NPT_DateTime::Format)format))) { parsed_last_time = date.ToString((NPT_DateTime::Format)format); break; } } m_MiscInfo.last_time = parsed_last_time; PLT_XmlHelper::GetChildText(entry, "playbackCount", str, didl_namespace_upnp); if (NPT_FAILED(str.ToInteger(value))) value = -1; m_MiscInfo.play_count = value; children.Clear(); PLT_XmlHelper::GetChildren(entry, children, "res"); for (NPT_Cardinal i=0; i<children.GetItemCount(); i++) { PLT_MediaItemResource resource; // extract url if (children[i]->GetText() == NULL) { NPT_LOG_WARNING_1("No resource text found in: %s", (const char*)PLT_XmlHelper::Serialize(*children[i])); } else { resource.m_Uri = children[i]->GetText()->SubString(0, 1024); // basic uri validation, ignoring scheme (could be rtsp) NPT_HttpUrl url(resource.m_Uri, true); if (!url.IsValid()) { NPT_LOG_WARNING_1("Invalid resource uri: %s", (const char*)resource.m_Uri); continue; } } // extract protocol info NPT_String protocol_info; res = PLT_XmlHelper::GetAttribute(children[i], "protocolInfo", protocol_info, "", 256); if (NPT_FAILED(res)) { NPT_LOG_WARNING_1("No protocol info found in: %s", (const char*)PLT_XmlHelper::Serialize(*children[i])); } else { resource.m_ProtocolInfo = PLT_ProtocolInfo(protocol_info); if (!resource.m_ProtocolInfo.IsValid()) { NPT_LOG_WARNING_1("Invalid resource protocol info: %s", (const char*)protocol_info); } } // extract known attributes PLT_XmlHelper::GetAttribute(children[i], "protection", resource.m_Protection, "", 256); PLT_XmlHelper::GetAttribute(children[i], "resolution", resource.m_Resolution, "", 256); if (NPT_SUCCEEDED(PLT_XmlHelper::GetAttribute(children[i], "size", str, "", 256))) { if (NPT_FAILED(str.ToInteger64(resource.m_Size))) resource.m_Size = (NPT_Size)-1; } if (NPT_SUCCEEDED(PLT_XmlHelper::GetAttribute(children[i], "duration", str, "", 256))) { if (NPT_FAILED(PLT_Didl::ParseTimeStamp(str, resource.m_Duration))) { // if error while converting, ignore and set to -1 to indicate we don't know the duration resource.m_Duration = (NPT_UInt32)-1; PLT_XmlHelper::RemoveAttribute(children[i], "duration"); } else { // DLNA: reformat duration in case it was not compliant str = PLT_Didl::FormatTimeStamp(resource.m_Duration); PLT_XmlHelper::SetAttribute(children[i], "duration", str); } } m_Resources.Add(resource); } // re serialize the entry didl as a we might need to pass it to a renderer // we may have modified the tree to "fix" issues, so as not to break a renderer // (don't write xml prefix as this didl could be part of a larger document) //res = PLT_XmlHelper::Serialize(*entry, xml, false); m_Didl = ""; res = ToDidl(PLT_FILTER_MASK_ALL, m_Didl); NPT_CHECK_SEVERE(res); m_Didl = didl_header + m_Didl + didl_footer; return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | TestDateFromTimeStringW3C +---------------------------------------------------------------------*/ static void TestDateFromTimeStringW3C() { NPT_DateTime date; /* Valid date */ SHOULD_SUCCEED(date.FromString("2006-04-14T12:01:10.003Z", NPT_DateTime::FORMAT_W3C)); SHOULD_EQUAL_I(date.m_Year , 2006); SHOULD_EQUAL_I(date.m_Month , 4); SHOULD_EQUAL_I(date.m_Day , 14); SHOULD_EQUAL_I(date.m_Hours , 12); SHOULD_EQUAL_I(date.m_Minutes , 1); SHOULD_EQUAL_I(date.m_Seconds , 10); SHOULD_EQUAL_I(date.m_NanoSeconds , 3000000); SHOULD_EQUAL_I(date.m_TimeZone , 0); /* Valid date, 2 characters milliseconds */ SHOULD_SUCCEED(date.FromString("2006-04-14T12:01:10.02Z", NPT_DateTime::FORMAT_W3C)); SHOULD_EQUAL_I(date.m_Year , 2006); SHOULD_EQUAL_I(date.m_Month , 4); SHOULD_EQUAL_I(date.m_Day , 14); SHOULD_EQUAL_I(date.m_Hours , 12); SHOULD_EQUAL_I(date.m_Minutes , 1); SHOULD_EQUAL_I(date.m_Seconds , 10); SHOULD_EQUAL_I(date.m_NanoSeconds , 20000000); SHOULD_EQUAL_I(date.m_TimeZone , 0); /* Valid date, 1 character milliseconds */ SHOULD_SUCCEED(date.FromString("2006-04-14T12:01:10.9Z", NPT_DateTime::FORMAT_W3C)); SHOULD_EQUAL_I(date.m_Year , 2006); SHOULD_EQUAL_I(date.m_Month , 4); SHOULD_EQUAL_I(date.m_Day , 14); SHOULD_EQUAL_I(date.m_Hours , 12); SHOULD_EQUAL_I(date.m_Minutes , 1); SHOULD_EQUAL_I(date.m_Seconds , 10); SHOULD_EQUAL_I(date.m_NanoSeconds , 900000000); SHOULD_EQUAL_I(date.m_TimeZone , 0); /* Valid date, no millimseconds */ SHOULD_SUCCEED(date.FromString("2006-04-14T12:01:10Z", NPT_DateTime::FORMAT_W3C)); SHOULD_EQUAL_I(date.m_Year , 2006); SHOULD_EQUAL_I(date.m_Month , 4); SHOULD_EQUAL_I(date.m_Day , 14); SHOULD_EQUAL_I(date.m_Hours , 12); SHOULD_EQUAL_I(date.m_Minutes , 1); SHOULD_EQUAL_I(date.m_Seconds , 10); SHOULD_EQUAL_I(date.m_NanoSeconds , 0); SHOULD_EQUAL_I(date.m_TimeZone , 0); /* Valid date with microseconds, 'Z' */ SHOULD_SUCCEED(date.FromString("2005-09-06T17:16:10.003498Z", NPT_DateTime::FORMAT_W3C)); SHOULD_EQUAL_I(date.m_Year , 2005); SHOULD_EQUAL_I(date.m_Month , 9); SHOULD_EQUAL_I(date.m_Day , 6); SHOULD_EQUAL_I(date.m_Hours , 17); SHOULD_EQUAL_I(date.m_Minutes , 16); SHOULD_EQUAL_I(date.m_Seconds , 10); SHOULD_EQUAL_I(date.m_NanoSeconds , 3498000); SHOULD_EQUAL_I(date.m_TimeZone , 0); /* Valid date, no milliseconds, with timezone offset */ SHOULD_SUCCEED(date.FromString("2006-04-14T12:01:10+03:00", NPT_DateTime::FORMAT_W3C)); SHOULD_EQUAL_I(date.m_Year , 2006); SHOULD_EQUAL_I(date.m_Month , 4); SHOULD_EQUAL_I(date.m_Day , 14); SHOULD_EQUAL_I(date.m_Hours , 12); SHOULD_EQUAL_I(date.m_Minutes , 1); SHOULD_EQUAL_I(date.m_Seconds , 10); SHOULD_EQUAL_I(date.m_NanoSeconds , 0); SHOULD_EQUAL_I(date.m_TimeZone , 180); /* Valid date, no milliseconds, with negative m_TimeZone offset */ SHOULD_SUCCEED(date.FromString("2006-04-14T12:01:10-05:00", NPT_DateTime::FORMAT_W3C)); SHOULD_EQUAL_I(date.m_Year , 2006); SHOULD_EQUAL_I(date.m_Month , 4); SHOULD_EQUAL_I(date.m_Day , 14); SHOULD_EQUAL_I(date.m_Hours , 12); SHOULD_EQUAL_I(date.m_Minutes , 1); SHOULD_EQUAL_I(date.m_Seconds , 10); SHOULD_EQUAL_I(date.m_NanoSeconds , 0); SHOULD_EQUAL_I(date.m_TimeZone , -300); /* Valid date, with milliseconds, with positive m_TimeZone offset */ SHOULD_SUCCEED(date.FromString("2006-04-14T12:01:10.200+03:00", NPT_DateTime::FORMAT_W3C)); SHOULD_EQUAL_I(date.m_Year , 2006); SHOULD_EQUAL_I(date.m_Month , 4); SHOULD_EQUAL_I(date.m_Day , 14); SHOULD_EQUAL_I(date.m_Hours , 12); SHOULD_EQUAL_I(date.m_Minutes , 1); SHOULD_EQUAL_I(date.m_Seconds , 10); SHOULD_EQUAL_I(date.m_NanoSeconds , 200000000); SHOULD_EQUAL_I(date.m_TimeZone , 180); /* Valid date, with milliseconds, with negative m_TimeZone offset */ SHOULD_SUCCEED(date.FromString("2006-04-14T12:01:10.030-05:00", NPT_DateTime::FORMAT_W3C)); SHOULD_EQUAL_I(date.m_Year , 2006); SHOULD_EQUAL_I(date.m_Month , 4); SHOULD_EQUAL_I(date.m_Day , 14); SHOULD_EQUAL_I(date.m_Hours , 12); SHOULD_EQUAL_I(date.m_Minutes , 1); SHOULD_EQUAL_I(date.m_Seconds , 10); SHOULD_EQUAL_I(date.m_NanoSeconds , 30000000); SHOULD_EQUAL_I(date.m_TimeZone , -300); /* Valid date with microseconds and negative m_TimeZone offset */ SHOULD_SUCCEED(date.FromString("2005-09-06T17:16:10.001822-05:00", NPT_DateTime::FORMAT_W3C)); SHOULD_EQUAL_I(date.m_Year , 2005); SHOULD_EQUAL_I(date.m_Month , 9); SHOULD_EQUAL_I(date.m_Day , 6); SHOULD_EQUAL_I(date.m_Hours , 17); SHOULD_EQUAL_I(date.m_Minutes , 16); SHOULD_EQUAL_I(date.m_Seconds , 10); SHOULD_EQUAL_I(date.m_NanoSeconds , 1822000); SHOULD_EQUAL_I(date.m_TimeZone , -300); /* Valid date with microseconds and positive m_TimeZone offset */ SHOULD_SUCCEED(date.FromString("2005-09-06T17:16:10.001822+05:00", NPT_DateTime::FORMAT_W3C)); SHOULD_EQUAL_I(date.m_Year , 2005); SHOULD_EQUAL_I(date.m_Month , 9); SHOULD_EQUAL_I(date.m_Day , 6); SHOULD_EQUAL_I(date.m_Hours , 17); SHOULD_EQUAL_I(date.m_Minutes , 16); SHOULD_EQUAL_I(date.m_Seconds , 10); SHOULD_EQUAL_I(date.m_NanoSeconds , 1822000); SHOULD_EQUAL_I(date.m_TimeZone , 300); /* Invalid date with 3 digit year */ SHOULD_FAIL(date.FromString("206-04-14T12:01:10.003Z", NPT_DateTime::FORMAT_W3C)); /* Invalid date with 5 digit year */ SHOULD_FAIL(date.FromString("20076-04-14T12:01:10.003Z", NPT_DateTime::FORMAT_W3C)); /* Invalid date with 5 digit year */ SHOULD_FAIL(date.FromString("20076-04-14T12:01:10.003Z", NPT_DateTime::FORMAT_W3C)); /* Invalid date with garbage in the end */ SHOULD_FAIL(date.FromString("2006-04-14T12:01:10.003+69:696", NPT_DateTime::FORMAT_W3C)); /* Invalid date with bad month */ SHOULD_FAIL(date.FromString("2006-010-14T12:01:10.003", NPT_DateTime::FORMAT_W3C)); /* Invalid date with bad month, right overall length */ SHOULD_FAIL(date.FromString("2063-0--14T12:01:10.003", NPT_DateTime::FORMAT_W3C)); /* Invalid date with bad year-month separator */ SHOULD_FAIL(date.FromString("2063Y08-14T12:01:10.003", NPT_DateTime::FORMAT_W3C)); /* Invalid date with bad time separator */ SHOULD_FAIL(date.FromString("2063-08-14t12:01:10.003", NPT_DateTime::FORMAT_W3C)); /* Invalid date with bad hour */ SHOULD_FAIL(date.FromString("2063-08-14T012:01:10.003", NPT_DateTime::FORMAT_W3C)); /* Invalid date with bad GMT indicator */ SHOULD_FAIL(date.FromString("2063-08-14T12:01:10.003z", NPT_DateTime::FORMAT_W3C)); /* Invalid date with bad GMT indicator */ SHOULD_FAIL(date.FromString("2063-08-14T12:01:10.003g", NPT_DateTime::FORMAT_W3C)); /* Invalid date with millisecond separator but no digits */ SHOULD_FAIL(date.FromString("2063-08-14T12:01:10.", NPT_DateTime::FORMAT_W3C)); /* Invalid date with millisecond separator but no digits */ SHOULD_FAIL(date.FromString("2063-08-14T12:01:10.Z", NPT_DateTime::FORMAT_W3C)); /* Invalid date with millisecond separator but no digits */ SHOULD_FAIL(date.FromString("2063-08-14T12:01:10.+10:38", NPT_DateTime::FORMAT_W3C)); /* Invalid date with bad m_TimeZone offset */ SHOULD_FAIL(date.FromString("2063-08-14T12:01:10+10:338", NPT_DateTime::FORMAT_W3C)); /* Invalid date with bad m_TimeZone offset */ SHOULD_FAIL(date.FromString("2063-08-14T12:01:10+001:38", NPT_DateTime::FORMAT_W3C)); /* Invalid date with bad m_TimeZone offset */ SHOULD_FAIL(date.FromString("2063-08-14T12:01:10+10:33Z", NPT_DateTime::FORMAT_W3C)); /* Invalid date with bad m_TimeZone offset */ SHOULD_FAIL(date.FromString("2063-08-14T12:01:10.08+10:33Z", NPT_DateTime::FORMAT_W3C)); /* Invalid date with bad m_TimeZone offset with m_Seconds*/ SHOULD_FAIL(date.FromString("2063-08-14T12:01:10.08+10:33:30", NPT_DateTime::FORMAT_W3C)); /* Invalid date with m_TimeZone offset too big*/ SHOULD_FAIL(date.FromString("2063-08-14T12:01:10.08+14:33", NPT_DateTime::FORMAT_W3C)); }