The tool I use now Convert Time Field (Data Management) takes 5 to 6 hours to do this process.
The Convert Time Field tool should be able to process millions of records in minutes. Something is definitely off if it is taking that long for the number of records you have involved.
I agree with Joe that dictionaries are cool. Beyond being cool, they are at the core of so much of the Python language. All that said, I don't really see dictionaries as being well suited to your situation. Your situation isn't really if/else, it is more group by and increment.
Regarding your question of converting READING_DATE to BILLING_DATE, the answer partially depends on whether you are using ArcMap or ArcGIS Pro. How dates are returned from cursors and the field calculator varies between the two products.
After you having BILLING_DATE populated, the following code (adopted from Sort Field and then Calculate Sequential Values ) will give you the results using an approach that I think is more suited to your data.
import arcpy
from itertools import count, groupby
from operator import itemgetter
tbl =
case_fields = ["BILLING_DATE"]
increment_field = ["BILLING_MONTH"]
sql_orderby = "ORDER BY {}".format(", ".join(case_fields))
with arcpy.da.UpdateCursor(
tbl,
case_fields + increment_field,
sql_clause=(None, sql_orderby)
) as cursor:
counter = count()
case_func = itemgetter(*(cursor.fields.index(fld) for fld in case_fields))
for key, group in groupby(cursor, case_func):
key = key if isinstance(key, tuple) else (key,)
c = next(counter) + 1
for row in group:
cursor.updateRow(list(key) + [c])