Index: datetimemodule.c
===================================================================
--- datetimemodule.c	(revision 57274)
+++ datetimemodule.c	(working copy)
@@ -947,7 +947,7 @@
 		result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg);
 
 	if (result != NULL && result != Py_None) {
-		if (!PyString_Check(result) && !PyUnicode_Check(result)) {
+		if (!PyUnicode_Check(result)) {
 			PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must "
 				     "return None or a string, not '%s'",
 				     Py_Type(result)->tp_name);
@@ -1133,7 +1133,7 @@
 {
 	PyObject *temp;
 	PyObject *tzinfo = get_tzinfo_member(object);
-	PyObject *Zreplacement = PyString_FromString("");
+	PyObject *Zreplacement = PyBytes_FromStringAndSize("", 1);
 	if (Zreplacement == NULL)
 		return NULL;
 	if (tzinfo == Py_None || tzinfo == NULL)
@@ -1166,8 +1166,17 @@
 		Py_INCREF(Zreplacement2);
 		Py_DECREF(Zreplacement);
 		Zreplacement = Zreplacement2;
+		/*
+			There's nothing like _PyUnicode_AsDefaultEncodedBytes (yet?), therefore
+			the String has to be converted to bytes to keep it consistent with the
+			context
+		*/
+		Zreplacement2 = PyBytes_FromStringAndSize(PyString_AsString(Zreplacement), PyString_Size(Zreplacement));
+		Py_DECREF(Zreplacement);
+		Py_INCREF(Zreplacement2);
+		Zreplacement = Zreplacement2;
 	}
-	if (!PyString_Check(Zreplacement)) {
+	if (!PyBytes_Check(Zreplacement)) {
 		PyErr_SetString(PyExc_TypeError,
 				"tzname.replace() did not return a string");
 		goto Error;
@@ -1209,11 +1218,13 @@
 	int ntoappend;	/* # of bytes to append to output buffer */
 
 	assert(object && format && timetuple);
-	assert(PyString_Check(format) || PyUnicode_Check(format));
+	assert(PyUnicode_Check(format));
+    /* Convert the input format to a C string and size */
+    pin = PyUnicode_AsString(format);
+    if(!pin)
+    	return NULL;
+    flen = PyUnicode_GetSize(format);
 
-        /* Convert the input format to a C string and size */
-        if (PyObject_AsCharBuffer(format, &pin, &flen) < 0)
-		return NULL;
 
 	/* Give up if the year is before 1900.
 	 * Python strftime() plays games with the year, and different
@@ -1245,9 +1256,9 @@
 	 * is expensive, don't unless they're actually used.
 	 */
 	totalnew = flen + 1;	/* realistic if no %z/%Z */
-	newfmt = PyString_FromStringAndSize(NULL, totalnew);
+	newfmt = PyBytes_FromStringAndSize(NULL, totalnew);
 	if (newfmt == NULL) goto Done;
-	pnew = PyString_AsString(newfmt);
+	pnew = PyBytes_AsString(newfmt);
 	usednew = 0;
 
 	while ((ch = *pin++) != '\0') {
@@ -1267,7 +1278,7 @@
 				/* format utcoffset */
 				char buf[100];
 				PyObject *tzinfo = get_tzinfo_member(object);
-				zreplacement = PyString_FromString("");
+				zreplacement = PyBytes_FromStringAndSize("", 1);
 				if (zreplacement == NULL) goto Done;
 				if (tzinfo != Py_None && tzinfo != NULL) {
 					assert(tzinfoarg != NULL);
@@ -1278,13 +1289,13 @@
 							     tzinfoarg) < 0)
 						goto Done;
 					Py_DECREF(zreplacement);
-					zreplacement = PyString_FromString(buf);
+					zreplacement = PyBytes_FromStringAndSize(buf, strlen(buf));
 					if (zreplacement == NULL) goto Done;
 				}
 			}
 			assert(zreplacement != NULL);
-			ptoappend = PyString_AS_STRING(zreplacement);
-			ntoappend = PyString_GET_SIZE(zreplacement);
+			ptoappend = PyBytes_AS_STRING(zreplacement);
+			ntoappend = strlen(ptoappend);
 		}
 		else if (ch == 'Z') {
 			/* format tzname */
@@ -1295,9 +1306,9 @@
 					goto Done;
 			}
 			assert(Zreplacement != NULL);
-			assert(PyString_Check(Zreplacement));
-			ptoappend = PyString_AS_STRING(Zreplacement);
-			ntoappend = PyString_GET_SIZE(Zreplacement);
+			assert(PyBytes_Check(Zreplacement));
+			ptoappend = PyBytes_AS_STRING(Zreplacement);
+			ntoappend = strlen(ptoappend);
 		}
 		else {
 			/* percent followed by neither z nor Z */
@@ -1318,10 +1329,10 @@
  				PyErr_NoMemory();
  				goto Done;
  			}
- 			if (_PyString_Resize(&newfmt, bigger) < 0)
+ 			if (PyBytes_Resize(newfmt, bigger) < 0)
  				goto Done;
  			totalnew = bigger;
- 			pnew = PyString_AsString(newfmt) + usednew;
+ 			pnew = PyBytes_AsString(newfmt) + usednew;
  		}
 		memcpy(pnew, ptoappend, ntoappend);
 		pnew += ntoappend;
@@ -1329,14 +1340,14 @@
 		assert(usednew <= totalnew);
 	}  /* end while() */
 
-	if (_PyString_Resize(&newfmt, usednew) < 0)
+	if (PyBytes_Resize(newfmt, usednew) < 0)
 		goto Done;
 	{
 		PyObject *time = PyImport_ImportModule("time");
 		if (time == NULL)
 			goto Done;
 		result = PyObject_CallMethod(time, "strftime", "OO",
-					     newfmt, timetuple);
+					     PyUnicode_FromString(PyBytes_AS_STRING(newfmt)), timetuple);
 		Py_DECREF(time);
     	}
  Done:
@@ -2420,7 +2431,7 @@
 	PyObject *tuple;
 	static char *keywords[] = {"format", NULL};
 
-	if (! PyArg_ParseTupleAndKeywords(args, kw, "S:strftime", keywords,
+	if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords,
 					  &format))
 		return NULL;
 
@@ -2511,18 +2522,36 @@
 	return clone;
 }
 
-static PyObject *date_getstate(PyDateTime_Date *self, int hashable);
+/*
+	Borrowed from stringobject.c, originally it was string_hash()
+*/
+static long
+generic_hash(unsigned char *data, int len)
+{
+	register unsigned char *p;
+	register long x;
 
+	p = (unsigned char *) data;
+	x = *p << 7;
+	while (--len >= 0)
+		x = (1000003*x) ^ *p++;
+	x ^= len;
+	if (x == -1)
+		x = -2;
+
+	return x;
+}
+
+
+static PyObject *date_getstate(PyDateTime_Date *self);
+
 static long
 date_hash(PyDateTime_Date *self)
 {
-	if (self->hashcode == -1) {
-		PyObject *temp = date_getstate(self, 1);
-		if (temp != NULL) {
-			self->hashcode = PyObject_Hash(temp);
-			Py_DECREF(temp);
-		}
-	}
+	if (self->hashcode == -1)
+		self->hashcode = generic_hash(
+			(unsigned char *)self->data, _PyDateTime_DATE_DATASIZE);
+		
 	return self->hashcode;
 }
 
@@ -2545,22 +2574,18 @@
 
 /* __getstate__ isn't exposed */
 static PyObject *
-date_getstate(PyDateTime_Date *self, int hashable)
+date_getstate(PyDateTime_Date *self)
 {
 	PyObject* field;
-	if (hashable)
-		field = PyString_FromStringAndSize(
-			(char*)self->data, _PyDateTime_DATE_DATASIZE);
-	else
-		field = PyBytes_FromStringAndSize(
-			(char*)self->data, _PyDateTime_DATE_DATASIZE);
+	field = PyBytes_FromStringAndSize(
+		(char*)self->data, _PyDateTime_DATE_DATASIZE);
 	return Py_BuildValue("(N)", field);
 }
 
 static PyObject *
 date_reduce(PyDateTime_Date *self, PyObject *arg)
 {
-	return Py_BuildValue("(ON)", Py_Type(self), date_getstate(self, 0));
+	return Py_BuildValue("(ON)", Py_Type(self), date_getstate(self));
 }
 
 static PyMethodDef date_methods[] = {
@@ -3246,9 +3271,11 @@
 			return -1;
 
 		/* Reduce this to a hash of another object. */
-		if (offset == 0)
-			temp = PyString_FromStringAndSize((char *)self->data,
-						_PyDateTime_TIME_DATASIZE);
+		if (offset == 0) {
+			self->hashcode = generic_hash(
+				(unsigned char *)self->data, _PyDateTime_TIME_DATASIZE);
+			return self->hashcode;
+		}
 		else {
 			int hour;
 			int minute;
@@ -3765,12 +3792,12 @@
 	PyObject *result = NULL, *obj, *module;
 	const char *string, *format;
 
-	if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format))
+	if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format))
 		return NULL;
 
 	if ((module = PyImport_ImportModule("time")) == NULL)
 		return NULL;
-	obj = PyObject_CallMethod(module, "strptime", "ss", string, format);
+	obj = PyObject_CallMethod(module, "strptime", "uu", string, format);
 	Py_DECREF(module);
 
 	if (obj != NULL) {
@@ -4154,10 +4181,11 @@
 			return -1;
 
 		/* Reduce this to a hash of another object. */
-		if (n == OFFSET_NAIVE)
-			temp = PyString_FromStringAndSize(
-					(char *)self->data,
-					_PyDateTime_DATETIME_DATASIZE);
+		if (n == OFFSET_NAIVE) {
+			self->hashcode = generic_hash(
+				(unsigned char *)self->data, _PyDateTime_DATETIME_DATASIZE);
+			return self->hashcode;
+		}
 		else {
 			int days;
 			int seconds;
Index: timemodule.c
===================================================================
--- timemodule.c	(revision 57274)
+++ timemodule.c	(working copy)
@@ -377,13 +377,17 @@
 	PyObject *tup = NULL;
 	struct tm buf;
 	const char *fmt;
+	PyObject *format;
 	size_t fmtlen, buflen;
 	char *outbuf = 0;
 	size_t i;
 
 	memset((void *) &buf, '\0', sizeof(buf));
 
-	if (!PyArg_ParseTuple(args, "s|O:strftime", &fmt, &tup))
+	/* Will always expect a unicode string to be passed as format.
+	   Given that there's no str type anymore in py3k this seems safe.
+	*/
+	if (!PyArg_ParseTuple(args, "U|O:strftime", &format, &tup))
 		return NULL;
 
 	if (tup == NULL) {
@@ -458,6 +462,9 @@
             return NULL;
         }
 
+    /* Convert the unicode string to an ascii one */
+    fmt = PyUnicode_AsString(format);
+
 	fmtlen = strlen(fmt);
 
 	/* I hate these functions that presume you know how big the output
@@ -535,7 +542,7 @@
 	p = asctime(&buf);
 	if (p[24] == '\n')
 		p[24] = '\0';
-	return PyString_FromString(p);
+	return PyUnicode_FromString(p);
 }
 
 PyDoc_STRVAR(asctime_doc,
@@ -571,7 +578,7 @@
 	}
 	if (p[24] == '\n')
 		p[24] = '\0';
-	return PyString_FromString(p);
+	return PyUnicode_FromString(p);
 }
 
 PyDoc_STRVAR(ctime_doc,
