diff --git a/twisted/internet/base.py b/twisted/internet/base.py
index 46e9217..5f10c6c 100644
--- a/twisted/internet/base.py
+++ b/twisted/internet/base.py
@@ -176,16 +176,7 @@ class DelayedCall:
         if self._str is not None:
             return self._str
         if hasattr(self, 'func'):
-            # This code should be replaced by a utility function in reflect;
-            # see ticket #6066:
-            if hasattr(self.func, '__qualname__'):
-                func = self.func.__qualname__
-            elif hasattr(self.func, '__name__'):
-                func = self.func.func_name
-                if hasattr(self.func, 'im_class'):
-                    func = self.func.im_class.__name__ + '.' + func
-            else:
-                func = reflect.safe_repr(self.func)
+            func = reflect.getFunctionName(self.func)
         else:
             func = None
 
diff --git a/twisted/internet/task.py b/twisted/internet/task.py
index 6e7b908..11afa17 100644
--- a/twisted/internet/task.py
+++ b/twisted/internet/task.py
@@ -244,17 +244,8 @@ class LoopingCall:
 
 
     def __repr__(self):
-        if hasattr(self.f, '__qualname__'):
-            func = self.f.__qualname__
-        elif hasattr(self.f, '__name__'):
-            func = self.f.__name__
-            if hasattr(self.f, 'im_class'):
-                func = self.f.im_class.__name__ + '.' + func
-        else:
-            func = reflect.safe_repr(self.f)
-
         return 'LoopingCall<%r>(%s, *%s, **%s)' % (
-            self.interval, func, reflect.safe_repr(self.a),
+            self.interval, reflect.getFunctionName(self.f), reflect.safe_repr(self.a),
             reflect.safe_repr(self.kw))
 
 
diff --git a/twisted/python/_reflectpy3.py b/twisted/python/_reflectpy3.py
index c0451e9..226bb20 100644
--- a/twisted/python/_reflectpy3.py
+++ b/twisted/python/_reflectpy3.py
@@ -286,6 +286,25 @@ def _determineClassName(x):
             return '<BROKEN CLASS AT 0x%x>' % unsignedID(c)
 
 
+def getFunctionName(funptr):
+    """
+    Return name of the function passed
+    
+    @param funptr: Searched function.
+    
+    @return: Function name or None if it does not exist for passed object
+    """ 
+    if hasattr( funptr , '__qualname__'):
+        func = funptr.__qualname__
+    elif hasattr( funptr, '__name__'):
+        func = funptr.func_name
+        if hasattr(funptr, 'im_class'):
+            func = funptr.im_class.__name__ + '.' + func
+    else:
+        func = safe_repr(funptr)
+    return func
+
+
 def _safeFormat(formatter, o):
     """
     Helper function for L{safe_repr} and L{safe_str}.
diff --git a/twisted/python/test/test_reflectpy3.py b/twisted/python/test/test_reflectpy3.py
index acd8f8d..8722b10 100644
--- a/twisted/python/test/test_reflectpy3.py
+++ b/twisted/python/test/test_reflectpy3.py
@@ -350,6 +350,29 @@ class LookupsTestCase(TestCase):
 
 
 
+class GetFunctionNameTestCase(TestCase):
+    """
+    Tests for L{getFunctionName}.
+    """
+
+    def test_function(self):
+        """
+        L{getFunctionName} should return function name passed as a second argument.
+        """
+        self.assertEqual(
+            reflect.getFunctionName(reflect.getFunctionName),
+            "getFunctionName")
+
+    def test_memberFunction(self):
+        """
+        L{getFunctionName} should return fully qualified function name passed as a second argument.
+        """
+        self.assertEqual(
+            reflect.getFunctionName(self.test_memberFunction),
+            "GetFunctionNameTestCase.test_memberFunction")
+
+
+
 class Breakable(object):
 
     breakRepr = False
