Implement and test InternetTime{From,To}SystemTime{A,W}.
Correct spelling in InternetCheckConnectionA.

diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c
index 70ce9d5..c631826 100644
--- a/dlls/wininet/internet.c
+++ b/dlls/wininet/internet.c
@@ -2035,6 +2035,151 @@
     return InternetSetOptionW( hInternet, dwOption, lpBuffer, dwBufferLength );
 }
 
+static const WCHAR WININET_wkday[7][4] =
+    { { 'S','u','n', 0 }, { 'M','o','n', 0 }, { 'T','u','e', 0 }, { 'W','e','d', 0 },
+      { 'T','h','u', 0 }, { 'F','r','i', 0 }, { 'S','a','t', 0 } };
+static const WCHAR WININET_month[12][4] =
+    { { 'J','a','n', 0 }, { 'F','e','b', 0 }, { 'M','a','r', 0 }, { 'A','p','r', 0 },
+      { 'M','a','y', 0 }, { 'J','u','n', 0 }, { 'J','u','l', 0 }, { 'A','u','g', 0 },
+      { 'S','e','p', 0 }, { 'O','c','t', 0 }, { 'N','o','v', 0 }, { 'D','e','c', 0 } };
+
+/***********************************************************************
+ *           InternetTimeFromSystemTimeA (WININET.@)
+ */
+BOOL WINAPI InternetTimeFromSystemTimeA( const SYSTEMTIME* time, DWORD format, LPSTR string, DWORD size )
+{
+    BOOL ret;
+    WCHAR stringW[INTERNET_RFC1123_BUFSIZE];
+
+    TRACE( "%p 0x%08lx %p 0x%08lx\n", time, format, string, size );
+
+    ret = InternetTimeFromSystemTimeW( time, format, stringW, sizeof(stringW) );
+    if (ret) WideCharToMultiByte( CP_ACP, 0, stringW, -1, string, size, NULL, NULL );
+
+    return ret;
+}
+
+/***********************************************************************
+ *           InternetTimeFromSystemTimeW (WININET.@)
+ */
+BOOL WINAPI InternetTimeFromSystemTimeW( const SYSTEMTIME* time, DWORD format, LPWSTR string, DWORD size )
+{
+    static const WCHAR date[] =
+        { '%','s',',',' ','%','0','2','d',' ','%','s',' ','%','4','d',' ','%','0',
+          '2','d',':','%','0','2','d',':','%','0','2','d',' ','G','M','T', 0 };
+
+    TRACE( "%p 0x%08lx %p 0x%08lx\n", time, format, string, size );
+
+    if (!time || !string) return FALSE;
+
+    if (format != INTERNET_RFC1123_FORMAT || size < INTERNET_RFC1123_BUFSIZE * sizeof(WCHAR))
+        return FALSE;
+
+    sprintfW( string, date,
+              WININET_wkday[time->wDayOfWeek],
+              time->wDay,
+              WININET_month[time->wMonth - 1],
+              time->wYear,
+              time->wHour,
+              time->wMinute,
+              time->wSecond );
+
+    return TRUE;
+}
+
+/***********************************************************************
+ *           InternetTimeToSystemTimeA (WININET.@)
+ */
+BOOL WINAPI InternetTimeToSystemTimeA( LPCSTR string, SYSTEMTIME* time, DWORD reserved )
+{
+    BOOL ret = FALSE;
+    WCHAR *stringW;
+    int len;
+
+    TRACE( "%s %p 0x%08lx\n", debugstr_a(string), time, reserved );
+
+    len = MultiByteToWideChar( CP_ACP, 0, string, -1, NULL, 0 );
+    stringW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+
+    if (stringW)
+    {
+        MultiByteToWideChar( CP_ACP, 0, string, -1, stringW, len );
+        ret = InternetTimeToSystemTimeW( stringW, time, reserved );
+        HeapFree( GetProcessHeap(), 0, stringW );
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *           InternetTimeToSystemTimeW (WININET.@)
+ */
+BOOL WINAPI InternetTimeToSystemTimeW( LPCWSTR string, SYSTEMTIME* time, DWORD reserved )
+{
+    unsigned int i;
+    WCHAR *s = (LPWSTR)string;
+
+    TRACE( "%s %p 0x%08lx\n", debugstr_w(string), time, reserved );
+
+    if (!string || !time || reserved != 0) return FALSE;
+
+    /*  Convert an RFC1123 time such as 'Fri, 07 Jan 2005 12:06:35 GMT' into
+     *  a SYSTEMTIME structure.
+     */
+
+    while (*s && !isalphaW( *s )) s++;
+    if (*s == '\0' || *(s + 1) == '\0' || *(s + 2) == '\0') return FALSE;
+    time->wDayOfWeek = 7;
+
+    for (i = 0; i < 7; i++)
+    {
+        if (toupperW( WININET_wkday[i][0] ) == toupperW( *s ) &&
+            toupperW( WININET_wkday[i][1] ) == toupperW( *(s + 1) ) &&
+            toupperW( WININET_wkday[i][2] ) == toupperW( *(s + 2) ) )
+        {
+            time->wDayOfWeek = i;
+            break;
+        }
+    }
+
+    if (time->wDayOfWeek > 6) return FALSE;
+    while (*s && !isdigitW( *s )) s++;
+    time->wDay = strtolW( s, &s, 10 );
+
+    while (*s && !isalphaW( *s )) s++;
+    if (*s == '\0' || *(s + 1) == '\0' || *(s + 2) == '\0') return FALSE;
+    time->wMonth = 0;
+
+    for (i = 0; i < 12; i++)
+    {
+        if (toupperW( WININET_month[i][0]) == toupperW( *s ) &&
+            toupperW( WININET_month[i][1]) == toupperW( *(s + 1) ) &&
+            toupperW( WININET_month[i][2]) == toupperW( *(s + 2) ) )
+        {
+            time->wMonth = i + 1;
+            break;
+        }
+    }
+    if (time->wMonth == 0) return FALSE;
+
+    while (*s && !isdigitW( *s )) s++;
+    if (*s == '\0') return FALSE;
+    time->wYear = strtolW( s, &s, 10 );
+
+    while (*s && !isdigitW( *s )) s++;
+    if (*s == '\0') return FALSE;
+    time->wHour = strtolW( s, &s, 10 );
+
+    while (*s && !isdigitW( *s )) s++;
+    if (*s == '\0') return FALSE;
+    time->wMinute = strtolW( s, &s, 10 );
+
+    while (*s && !isdigitW( *s )) s++;
+    if (*s == '\0') return FALSE;
+    time->wSecond = strtolW( s, &s, 10 );
+
+    time->wMilliseconds = 0;
+    return TRUE;
+}
 
 /***********************************************************************
  *	InternetCheckConnectionA (WININET.@)
@@ -2078,16 +2223,16 @@
   }
   else
   {
-     URL_COMPONENTSA componets;
+     URL_COMPONENTSA components;
 
-     ZeroMemory(&componets,sizeof(URL_COMPONENTSA));
-     componets.lpszHostName = (LPSTR)&host;
-     componets.dwHostNameLength = 1024;
+     ZeroMemory(&components,sizeof(URL_COMPONENTSA));
+     components.lpszHostName = (LPSTR)&host;
+     components.dwHostNameLength = 1024;
 
-     if (!InternetCrackUrlA(lpszUrl,0,0,&componets))
+     if (!InternetCrackUrlA(lpszUrl,0,0,&components))
        goto End;
 
-     TRACE("host name : %s\n",componets.lpszHostName);
+     TRACE("host name : %s\n",components.lpszHostName);
   }
 
   /*
diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c
index 54abec8..4970a9d 100644
--- a/dlls/wininet/tests/http.c
+++ b/dlls/wininet/tests/http.c
@@ -368,6 +368,79 @@
     ok( comp.dwExtraInfoLength == 29, "extra length wrong\n");
 }
 
+static void InternetTimeFromSystemTimeA_test()
+{
+    BOOL ret;
+    static const SYSTEMTIME time = { 2005, 1, 5, 7, 12, 6, 35, 0 };
+    char string[INTERNET_RFC1123_BUFSIZE];
+    static const char expect[] = "Fri, 07 Jan 2005 12:06:35 GMT";
+
+    ret = InternetTimeFromSystemTimeA( &time, INTERNET_RFC1123_FORMAT, string, sizeof(string) );
+    ok( ret, "InternetTimeFromSystemTimeA failed (%ld)\n", GetLastError() );
+
+    ok( !memcmp( string, expect, sizeof(expect) ),
+        "InternetTimeFromSystemTimeA failed (%ld)\n", GetLastError() );
+}
+
+static void InternetTimeFromSystemTimeW_test()
+{
+    BOOL ret;
+    static const SYSTEMTIME time = { 2005, 1, 5, 7, 12, 6, 35, 0 };
+    WCHAR string[INTERNET_RFC1123_BUFSIZE + 1];
+    static const WCHAR expect[] = { 'F','r','i',',',' ','0','7',' ','J','a','n',' ','2','0','0','5',' ',
+                                    '1','2',':','0','6',':','3','5',' ','G','M','T',0 };
+
+    ret = InternetTimeFromSystemTimeW( &time, INTERNET_RFC1123_FORMAT, string, sizeof(string) );
+    ok( ret, "InternetTimeFromSystemTimeW failed (%ld)\n", GetLastError() );
+
+    ok( !memcmp( string, expect, sizeof(expect) ),
+        "InternetTimeFromSystemTimeW failed (%ld)\n", GetLastError() );
+}
+
+static void InternetTimeToSystemTimeA_test()
+{
+    BOOL ret;
+    SYSTEMTIME time;
+    static const SYSTEMTIME expect = { 2005, 1, 5, 7, 12, 6, 35, 0 };
+    static const char string[] = "Fri, 07 Jan 2005 12:06:35 GMT";
+    static const char string2[] = " fri 7 jan 2005 12 06 35";
+
+    ret = InternetTimeToSystemTimeA( string, &time, 0 );
+    ok( ret, "InternetTimeToSystemTimeA failed (%ld)\n", GetLastError() );
+    ok( !memcmp( &time, &expect, sizeof(expect) ),
+        "InternetTimeToSystemTimeA failed (%ld)\n", GetLastError() );
+
+    ret = InternetTimeToSystemTimeA( string2, &time, 0 );
+    ok( ret, "InternetTimeToSystemTimeA failed (%ld)\n", GetLastError() );
+    ok( !memcmp( &time, &expect, sizeof(expect) ),
+        "InternetTimeToSystemTimeA failed (%ld)\n", GetLastError() );
+}
+
+static void InternetTimeToSystemTimeW_test()
+{
+    BOOL ret;
+    SYSTEMTIME time;
+    static const SYSTEMTIME expect = { 2005, 1, 5, 7, 12, 6, 35, 0 };
+    static const WCHAR string[] = { 'F','r','i',',',' ','0','7',' ','J','a','n',' ','2','0','0','5',' ',
+                                    '1','2',':','0','6',':','3','5',' ','G','M','T',0 };
+    static const WCHAR string2[] = { ' ','f','r','i',' ','7',' ','j','a','n',' ','2','0','0','5',' ',
+                                     '1','2',' ','0','6',' ','3','5',0 };
+    static const WCHAR string3[] = { 'F','r',0 };
+
+    ret = InternetTimeToSystemTimeW( string, &time, 0 );
+    ok( ret, "InternetTimeToSystemTimeW failed (%ld)\n", GetLastError() );
+    ok( !memcmp( &time, &expect, sizeof(expect) ),
+        "InternetTimeToSystemTimeW failed (%ld)\n", GetLastError() );
+
+    ret = InternetTimeToSystemTimeW( string2, &time, 0 );
+    ok( ret, "InternetTimeToSystemTimeW failed (%ld)\n", GetLastError() );
+    ok( !memcmp( &time, &expect, sizeof(expect) ),
+        "InternetTimeToSystemTimeW failed (%ld)\n", GetLastError() );
+
+    ret = InternetTimeToSystemTimeW( string3, &time, 0 );
+    ok( !ret, "InternetTimeToSystemTimeW failed (%ld)\n", GetLastError() );
+}
+
 START_TEST(http)
 {
     winapi_test(0x10000000);
@@ -375,4 +448,8 @@
     InternetCrackUrl_test();
     InternetOpenUrlA_test();
     InternetCrackUrlW_test();
+    InternetTimeFromSystemTimeA_test();
+    InternetTimeFromSystemTimeW_test();
+    InternetTimeToSystemTimeA_test();
+    InternetTimeToSystemTimeW_test();
 }
diff --git a/dlls/wininet/wininet.spec b/dlls/wininet/wininet.spec
index 7a2c32e..7eb91d2 100644
--- a/dlls/wininet/wininet.spec
+++ b/dlls/wininet/wininet.spec
@@ -159,8 +159,12 @@
 @ stdcall InternetSetStatusCallbackA(ptr ptr)
 @ stdcall InternetSetStatusCallbackW(ptr ptr)
 @ stub InternetShowSecurityInfoByURL
-@ stub InternetTimeFromSystemTime
-@ stub InternetTimeToSystemTime
+@ stdcall InternetTimeFromSystemTime(ptr long ptr long) InternetTimeFromSystemTimeA
+@ stdcall InternetTimeFromSystemTimeA(ptr long ptr long)
+@ stdcall InternetTimeFromSystemTimeW(ptr long ptr long)
+@ stdcall InternetTimeToSystemTime(str ptr long) InternetTimeToSystemTimeA
+@ stdcall InternetTimeToSystemTimeA(str ptr long)
+@ stdcall InternetTimeToSystemTimeW(wstr ptr long)
 @ stdcall InternetUnlockRequestFile(ptr)
 @ stdcall InternetWriteFile(ptr ptr long ptr)
 @ stub InternetWriteFileExA
diff --git a/include/wininet.h b/include/wininet.h
index 9fcf4d9..ed5cb5c 100644
--- a/include/wininet.h
+++ b/include/wininet.h
@@ -285,6 +285,7 @@
 BOOLAPI InternetTimeFromSystemTimeW(CONST SYSTEMTIME *,DWORD ,LPWSTR ,DWORD);
 #define InternetTimeFromSystemTime WINELIB_NAME_AW(InternetTimeFromSystemTime)
 
+#define INTERNET_RFC1123_FORMAT    0
 #define INTERNET_RFC1123_BUFSIZE   30
 
 BOOLAPI InternetTimeToSystemTimeA(LPCSTR ,SYSTEMTIME *,DWORD);