diff --git a/unix/modtime.c b/unix/modtime.c
index 2a907a7736efa6bf2e0db455138bcec3785eb040..b1b7a9079dcfb88086ddac643a8e8d7b140d0361 100644
--- a/unix/modtime.c
+++ b/unix/modtime.c
@@ -154,6 +154,16 @@ STATIC mp_obj_t mod_time_sleep_us(mp_obj_t arg) {
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_time_sleep_us_obj, mod_time_sleep_us);
 
+STATIC mp_obj_t mod_time_strftime(mp_uint_t n_args, const mp_obj_t *args) {
+    assert(n_args == 1);
+    time_t t = time(NULL);
+    struct tm *tm = localtime(&t);
+    char buf[32];
+    size_t sz = strftime(buf, sizeof(buf), mp_obj_str_get_str(args[0]), tm);
+    return mp_obj_new_str(buf, sz, false);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_time_strftime_obj, 1, 2, mod_time_strftime);
+
 STATIC const mp_rom_map_elem_t mp_module_time_globals_table[] = {
     { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_utime) },
     { MP_ROM_QSTR(MP_QSTR_clock), MP_ROM_PTR(&mod_time_clock_obj) },
@@ -164,6 +174,7 @@ STATIC const mp_rom_map_elem_t mp_module_time_globals_table[] = {
     { MP_ROM_QSTR(MP_QSTR_ticks_ms), MP_ROM_PTR(&mod_time_ticks_ms_obj) },
     { MP_ROM_QSTR(MP_QSTR_ticks_us), MP_ROM_PTR(&mod_time_ticks_us_obj) },
     { MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mod_time_ticks_diff_obj) },
+    { MP_ROM_QSTR(MP_QSTR_strftime), MP_ROM_PTR(&mod_time_strftime_obj) },
 };
 
 STATIC MP_DEFINE_CONST_DICT(mp_module_time_globals, mp_module_time_globals_table);
diff --git a/unix/qstrdefsport.h b/unix/qstrdefsport.h
index 7323b97a4d986927ece57b0a4a93b68f0616d831..608234e2323d517c77c5cbc90feddab8bb1af8b0 100644
--- a/unix/qstrdefsport.h
+++ b/unix/qstrdefsport.h
@@ -77,6 +77,7 @@ Q(sleep_us)
 Q(ticks_ms)
 Q(ticks_us)
 Q(ticks_diff)
+Q(strftime)
 
 Q(socket)
 Q(sockaddr)